Pulling icanhaz templates from a remote server - html

The icanhaz documentation uses this as an example as how to pull ich templates from a remote server.
$.getJSON('/myserver/templates.json', function (templates) {
$.each(templates, function (template) {
ich.addTemplate(template.name, template.template);
});
});
However, the documentation doesn't really tell you what the file on the remote server has to look like. Anyone have any ideas?

Your templates JSON object may look like this:
{
"templates": {"name": "optionTemplate",
"template": "{{#options}}<option value='{{value}}'>{{display}}</option>{{/options}}"
}
}
This will define a template for options in a select box.
You can add the template using the code you specified (actually I tweaked it slightly as I couldn't get it to work as specified):
$.getJSON('templates.json', function (templates) {
$.each(templates, function () {
ich.addTemplate(this.name, this.template);
});
});
//now call getJSON on your input data
$.getJSON('options.json', function (data) {
var optionElements = ich.optionTemplate(data);
$('#selectBox').append(optionElements);
}
For clarity, here is what options.json contains:
{
"options": [
{ "value": "optionValue",
"display": "optionDisplay"
},
{ "value": "optionValue2",
"display": "optionDisplay2"
}]
}
Do let me know how you get on :)

Related

Can I use jsTree preloaded with JSON data and also use Ajax

I have jsTree working with JSON data: the JSON data represents the server's file system, and the user can select a folder from the tree, which is then added to the folder input field). I don't want the page to load without the top three levels of the file system provided. However, I don't parse the whole file system because that would take too long.
Can I pre-populate jsTree with JSON data and use Ajax when the user opens nodes further down the tree which were not pre-populated, or do I have to use Ajax for the initial load as well?
Below I show my current code (without any Ajax), but only retrieving data down to one level for the sake of brevity: it returns C:\ and E:\ file systems from the server. This works, but I'm unclear how to introduce Ajax to this when the user tries to open a node further down the hierarchy.
<label for="folder">Selected Folder</label>
<input type="text" name="folder" id="folder">
<br>
<script type="text/javascript">
function createJSTree(jsondata)
{
$('#jstree').jstree(
{
"plugins" : ["themes","html_data","ui","cookie"],
'core':
{
'data': jsondata
}
}
)
.bind("select_node.jstree",
function (e, data)
{
var objNode = data.instance.get_node(data.selected);
document.getElementById('folder').value=objNode.id;
}
)
;
}
$(function() { var jsondata ={"text":"pclaptop","children":[{"id":"C:\\","text":"C:\\","children":[]},{"id":"E:\\","text":"E:\\","children":[]}]}; createJSTree(jsondata); })
</script>
Before I get into the ajax piece of the code I had to set the check_callback parameter in jsTree it enables editing of the jsTree. Next, I call `$('#jstree').jstree().create_node('#', parsedData, "last"); in the success method of jQuery's ajax call, and that did the trick. My solution is below:
index.html
<label for="folder">Selected Folder</label>
<input type="text" name="folder" id="folder">
<br>
<button id="create-node-button">
Create Node
</button>
<div id="jstree"></div>
<script type="text/javascript">
function createJSTree(jsondata) {
$('#jstree').jstree({
"plugins": ["themes", "html_data", "ui", "cookie"],
'core': {
'check_callback': true,
'data': jsondata
}
})
.bind("select_node.jstree",
function(e, data) {
var objNode = data.instance.get_node(data.selected);
document.getElementById('folder').value = objNode.id;
}
);
}
$(function() {
var jsondata = [{
"id": "pclaptop",
"parent": "#",
"text": "pclaptop"
},
{
"id": "C:\\",
"parent": "pclaptop",
"text": "C:\\"
},
{
"id": "E:\\",
"parent": "pclaptop",
"text": "E:\\"
},
{
"id": "F:\\",
"parent": "pclaptop",
"text": "F:\\"
}
];
createJSTree(jsondata);
$("#create-node-button").on("click", function() {
$.ajax({
url: "./data.json",
success: function(data){
var parsedData = JSON.parse(data);
$('#jstree').jstree().create_node('#', parsedData, "last");
}
});
});
});
</script>
data.json
{ "id" : "ajson5", "text" : "newly added" }
Lastly, here is a fiddle . I wasn't sure of how to properly set up the ajax call in jsfiddle so I did it locally instead.

How to route all in matchCondition ?

I'm working on a Azure Functions App and i have some issues with the routes, when I add a matching rule with * inside, it doesn't work anymore. Anyone have an idea of what I'm doing wrong ?
When I uncomment one of the other rules or just change the route of Test Route from /{code} to /{*code}, it fails and gives me the Bad Request response.
My routing file proxies.json
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"Test Route": {
"matchCondition": {
"route": "/{code}"
},
"backendUri": "https://%WEBSITE_HOSTNAME%/api/UrlTester/{code}"
}
//,
//"Let's Encrypt Support" : {
// "matchCondition": {
// "route": "/.well-known/acme-challenge/{*code}"
// },
// "backendUri": "https://%WEBSITE_HOSTNAME%/api/LetsEncrypt/{code}"
//},
//"Domain Redirect": {
// "matchCondition": {
// "route": "/{*shortUrl}"
// },
// "backendUri": "http://%WEBSITE_HOSTNAME%/api/UrlRedirect/{shortUrl}"
//},
//"Api": {
// "matchCondition": {
// "route": "/api/{*path}"
// },
// "backendUri": "http://%WEBSITE_HOSTNAME%/api/{path}"
//}
}
}
I'm using this following fork: https://github.com/duijvelshoff/serverless-url-shortener
And this documentation: https://learn.microsoft.com/en-us/azure/azure-functions/functions-proxies
Thanks.
As per this github issue a catchall {* route redirecting to the same function app will cause a 400 response.
Moving your HTTP triggered functions to a separate function app, and changing the backend URLs will fix your issues.
try something like "route": "id={code}"

Angular 4 httpclient mapping observable to nested json

With the help of the forum I was able to get my httpclient observable mapping issue sorted with this syntax;
this._http.get<DomainMetaData>(serviceURL);
which works great! However, I have a json response coming back from the server which is nested and wonder if I can use the same syntax as I'm currently using or if I need to now manually .map the response into my classes?
Based on posts I've seen here on SO I've created two classes to represent the nested structure of the response JSON (see below).
The function call...
getDomainMetaData(domain): Observable<DomainMetaData> {
let serviceURL = "http://localhost:3000/selectdomains?domain=" + domain;
return this._http.get<DomainMetaData>(serviceURL);
}
The classes...
export class DomainMetaDataAttr {
constructor(public name: string,
public value: string) {
}
}
export class DomainMetaData {
constructor(public name: string,
public attributes: DomainMetaDataAttr[]) {
}
}
An example of the json...
//DomainMetaData
// {
// "ResponseMetadata": {
// "RequestId": "11f000bf-0dff-8a2a-31ff-8631a9f25b5b",
// "BoxUsage": "0.0008183545"
// },
// "Items": [
// {
// "Name": "2",
// "Attributes": [
// {
// "Name": "Document Date",
// "Value": "22/03/13"
// },
// {
// "Name": "Document Ref",
// "Value": "Doc test"
// }
// ]
// },
I love the neatness and simplicity of my current solution but I appreciate I may now have to change my code!
Many Thanks.
If I understand correctly you want to know how to use the JSON response from an HttpClient call.
I currently approach it like this:
// x.service.ts
getData() {
return this.http.get(URL);
}
// x.component.ts
this.service.getData().subscribe(res => {
if (res['data']) {
const data = res['data'];
// do whatever with the data
}
});
With the above approach you can run whatever methods / filters you want on the JSON e.g. map over the array and pull data out / mutate it, etc. Not sure if it's necessary to create additional classes to deal with the nested JSON data.
Oops! The code I posted actually works, I just wasn't referencing the results in the attributes array correctly.
Thanks for taking the time to look at this.

AngularJS - How to data bind an object within a JSON object

Using the included http post, I should get back the JSON object below. I want to take the LeagueDictionary data in the JSON below and create an object so I can use it in a for each loop on my client, but I can't wrap my head around how to structure that code in the http call.
{
"Id": 0,
"UserName": null,
"NickName": null,
"Email": "email#company.com",
"Password": null,
"Admin": false,
"Validated": false,
"Key": "oOE0QbOhjK17pNeKDPEFti5On27R3b",
"LeagueDictionary": {
"1": "League #1",
"2": "League #2"
}
}
using this call:
$scope.getLeagues = function() {
$http({
method: 'POST',
url: 'http://xxxxxxxxxxxxxxxxxx',
data: ???,
})
}
If someone give me a nudge on how to data bind that particular part of the JSON, I'd appreciate the help. I'm not sure how to strip the LeagueDictionary section out and make an object out of it.
You could set up a service that gets your data, so you can get $http and such out of your controller. Say...
app.factory('DataService', function ($http) {
return {
get: function () {
return $http.get('data.json'); // post & url goes here
}
};
});
In your controller, use then to access the response data after promise has been resolved (catch() and finally() are available, too).
app.controller('MainCtrl', function ($scope, DataService) {
DataService.get().then(function (response) {
$scope.leagueDictionary = response.data.LeagueDictionary;
});
});
Related HTML template would be
<body ng-controller="MainCtrl">
<div ng-show="leagueDictionary">
<span ng-repeat="(key,val) in leagueDictionary">
{{ val }} <br>
</span>
</div>
</body>
Using your data this gives you
See example plunker here http://plnkr.co/edit/j6bmmQ
You can just access the LeagueDictionary property of the response, and then iterate over that in ng-repeat. Obviously I don't know exactly what your scopes look like, but this should get you started:
//JS
$http.post('/someUrl', { 'foo': 'bar' }).success(function(data) {
myController.myModel.leagueDictionary = data.LeagueDictionary;
});
//HTML
<tr ng-repeat="(leagueNum, leagueName) in leagueDictionary">

Angular JS detailed view with only one json

I'm introducing in Angular with its Tutorial "Phonecat".
Against the tutorial I'd like to build a simple app with a list and detail view with only one json, containing all informations.
The list-view (showing complete content of the json) works fine but I'm struggle with how to set my Angular services for the detail-view.
I am using the XHR method:
Controller.js:
function PlaygroundDetailCtrl($scope, Playground) {
$scope.playgrounds = Playground.query();
}
Services.js
angular.module('playgroundcatServices', ['ngResource']).
factory('Playground', function($resource){
return $resource('playgrounds/playgrounds.json', {}, {
query: {method:'GET', isArray:true}
});
});
playground.json
[
{
"id:" 1,
"properties": "true"
"lat": "51.347789"
"lon": "12.232234"
},
{
"id:" 2,
"properties": "false"
"lat": "51.347789"
"lon": "12.766667"
}
]
I want Angular to display only one entry (id:1) with its properties.
What is the smartest way to do that: showing again all and then filter?
I am stumped.
Use an Angular filter on your view (there's no need to filter the data on the service):
<div ng-repeat="entry in playgrounds | filter:{id: 1}">
<p>properties: {{entry.properties}}</p>
<p>lat: {{entry.lat}}</p>
<p>lon: {{entry.lon}}</p>
</div>
jsfiddle: http://jsfiddle.net/bmleite/Ad6u9/
This worked out quite good:
Controller:
function PlaygroundDetailCtrl($scope, $routeParams, $http) {
$http.get('playgrounds/playgrounds.json').success(function(data){
angular.forEach(data, function(item) {
if (item.id == $routeParams.playgroundId)
$scope.playground = item;
});
});
I've got exactly the same scenario now I think (I'm guessing you're developing with 'mobile' in mind (as I am and want to minimise data transfer) - I'm using one 'master json file', and then on my detail view just filtering that json file (so that the json doesn't have to be reloaded) on the ID value.
This is totally untested but your code from the original question should be modified something like this:
angular.module('playgroundcatServices', ['ngResource'])
.factory('Playground', function($resource){
return $resource('playgrounds/playgrounds.json', {}, {
query: {method:'GET', isArray:true}
});
});
function PlaygroundDetailCtrl($scope, Playground) {
Playground.query(
// params (none in this case)
{},
// Success
function (data) {
$scope.playgrounds = data.filter(function (o) {
return o.id == $routeParams.playgroundId; // assuming you've set this up in your routes definition
})[0];
},
// Error
function (data) {
//error handling goes here
}
);
}
You may want to put something like $scope.isDataLoaded = true; in your 'success' handler as well, and do a watch on that, to use to check to see when the data has finished loading (eg. for in a directive).
I'm not super happy with the [0] in there, but it think the solution is better than a forEach loop myself.