Hi this is my first attempt to use MustacheJS with a JSON webservice in .net
Currently I am struggling I can't seem to find what I am doing wrong setting this basic example:
My Webservice is returing the following string:
[
{
"ShortDescription":"BOX",
"Description":"BOXING",
"Id":1
},
{
"ShortDescription":"EPL",
"Description":"ENGLISH PREMIER LEAGUE",
"Id":2
}
]
I have validated its syntax with this website: http://json.parser.online.fr/
and here is the HTML code I am using:
google.load("jquery", "1");
google.setOnLoadCallback(function () {
$(document).ready(
function () {
$.ajax({
url: "../data.asmx/geteagues",
type: "POST",
dataType: "json",
data: "",
contentType: "application/json; charset=utf-8",
success: function (data) {
var template = "<h1>{{ShortDescription}} {{Description}}</h1>";
var html = Mustache.render(template, data);
$('#sampleArea').html(html);
alert(html);
}
})
}
)
});
I am posting the whole JS code, since I am not very good with javascript, basically I want to load always the latest JQuery version from google and then work my WS call.
The problem so far is that when I place a breakpoint in the following line:
var html = Mustache.render(template, data);
I see that the template is setn ok, and so does the data, same value as I posted above, but the .render function is returning: I seems It didnt like the data.
So far all the examples I have seen for inline data come as the following structure:
{
"repo": [
{ "name": "resque" },
{ "name": "hub" },
{ "name": "rip" },
]
}
And then a template defined like this:
{{#repo}}
<b>{{name}}</b>
{{/repo}}
But the only difference of that against my data is that I dont have a "parent" like "repo"
At server side, I am using a .net library called JSON.net and in the documentation of how are collections being serialized:
james.newtonking.com/projects/json/help/html/SerializingCollections.htm
the final result does not include the parent node's name, which I thing is missing from my Mustache Template definition:
[
{
"Name": "Product 1",
"ExpiryDate": "2000-12-29T00:00Z",
"Price": 99.95,
"Sizes": null
},
{
"Name": "Product 2",
"ExpiryDate": "2009-07-31T00:00Z",
"Price": 12.50,
"Sizes": null
}
]
Is this what I am missing? the "repo" parent node from my data so I can iterate my Template?
Thanks in advance for your time.
-ed
Per #stealth on this question Mustache.js: Iterate over a list received via json
{{ #. }}
<b>{{Name}}</b>
{{ /. }}
Note the only difference from #stealth's answer is a "#" instead of "/".
The line data = { 'roles': data }; is the most crucial. Its attaching the key to the data returned by web api or any other source of data like pagemethods or web service
$.ajax({
dataType: "json",
url: '/api/TestApi/GetAllRole',
success: function (data) {
data = { 'roles': data }; // formatting the data to support the mustache format
var html = Mustache.to_html($('#RoleTemplate').html(), data);
$('#tblRole').append(html);
}
});
Few of my articles on the MustacheJs can be found here
INLINE FILTER FOR BASIC GRID USING MUSTACHEJS
http://www.techguides.in/add-inline-filter-to-basic-grid-using-mustache/
Master Details Grid on Demand data loading : Using Mustache.JS
http://www.techguides.in/master-details-grid-on-demand-data-loading-using-mustache-js/
Sorting a Grid using MustacheJs
http://www.techguides.in/enable-sorting-in-a-grid-bound-using-mustache-js/
short answer: YES
long answer: for security reasons [1], you need to wrap your JSON aray in an object anyways. for Mustache or any other library to be able to access your array you need to have at least one parent key on which you can base your iterator.
The "repo" key on your sample is the helper you need to tell mustache "go and iterate on the array that is inside the repo key", otherwise you have no way to tell the template what you want to output where
[1] this is just one of many resources you can find about why you need to wrap your JSON response in an object http://incompleteness.me/blog/2007/03/05/json-is-not-as-safe-as-people-think-it-is/
Related
I need help to upload document content back in Alfresco Community 5.2 though a share javascript.
The destination noderef is already existing, I upload a new version of a document.
I can't use the api/upload web service because I also need to do some operation on the noderef and I have a base64 content of the file which need to be converted.
So I wrote a new webscript and it is all working fine, at least while I upload documents which are smaller than 3MB,
Here it is the code
Alfresco.util.Ajax.request({
method: Alfresco.util.Ajax.POST,
dataObj: {
bytes: response.bytes,
digestAlgorithm: response.digestAlgorithm,
mimeType: response.mimeType.mimeTypeString,
name: response.name,
nodeRef: this.nodeRef,
signatureLevel: this.signatureLevel
},
url: thisClass.urlAlfrescoService + "myOrg/myPackage/uploadDocument",
successCallback: {
fn: thisClass._successOnUploadContent,
scope: this
},
failureCallback: {
fn: thisClass._errorOnUploadContent,
scope: this
},
scope: this,
noReloadOnAuthFailure: true
});
Do I miss some option to increase max upload file size?
I tryed uploading the file normally (with drag and drop) and it works.
The problem is when the file is >= 3MB the java class behind the webscript does not receive any byte
UPDATE
After some researches I found it could be a problem of how data are passed through POST, as application/x-www-form-urlencoded instead of multipart/form-data, but I can't find a way to specify the request content type in the ajax request
SOLUTION
The problem was the application/x-www-form-urlencoded instead of the multipart/form-data, I used a fetch POST request as stated here, but also the ajax request solution is good.
Last week,I had a same very similar problem with Alfresco AJAX request on Alfresco 5.0.2.5 and I used jquery's AJAX calls and it worked for me.
$.ajax({
url: Alfresco.constants.PROXY_URI + "your_web_script",
type: "POST",
data: dataFromFiles,
mimeType: "multipart/form-data",
contentType: false,
cache: false,
processData: false,
dataType: "text",
success: function(data, textStatus, jqXHR) {
},
error: function(jqXHR, textStatus, errorThrown) {
}
});
Reference link : https://blog.arvixe.com/sending-multipart-form-using-ajax/
Hope this helps you.
I am trying to do multiple $http post call and my code looks something like this:
var data = [{"id": 1, "Name": A}, {"id": 2, "Name": B},...];
var requests = [];
angular.forEach(data, function(value) {
requests.push($http(
url:'/example.com',
method: "POST",
dataType: 'json',
contentType:'application/json',
data:value ))
});
$q.all(requests).then(function(results){
results.forEach(function(data,status,headers,config){
console.log('success');
})
})
This works fine, but when the length of data array is more the number of service calls from client side is high. So I would like to make it as a batch request. Am not able to find any proper documentation for batch request for POST operation. Kindly help me on this.
I'm writing a meteor app and I'm trying to add an autocomplete feature to a search box. The data is very large and is on the server, so I can't have it all on the client. It's basically a database of users. If I'm not wrong, the mizzao:autocomplete package should make that possible, but I can't seem to get it to work.
Here's what I have on the server:
Meteor.publish('autocompleteViewers', function(selector, options) {
Autocomplete.publishCursor(viewers.find(selector, options), this);
this.ready();
});
And here are the settings I use for the search box on the client:
getSettings: function() {
return {
position: 'bottom',
limit: 5,
rules: [{
subscription: 'autocompleteViewers',
field: '_id',
matchAll: false,
options: '',
template: Template.vLegend
}],
};
}
But I keep getting this error on the client:
Error: Collection name must be specified as string for server-side search at validateRule
I don't really understand the problem. When I look at the package code, it just seems like it's testing whether the subscription field is a string and not a variable, which it is. Any idea what the problem could be? Otherwise is there a minimum working example I could go from somewhere? I couldn't find one in the docs.
Error: Collection name must be specified as string for server-side search at validateRule
You get this error because you don't specify a Collection name in quotes.
getSettings: function() {
return {
position: 'bottom',
limit: 5,
rules: [{
subscription: 'autocompleteViewers',
field: '_id',
matchAll: false,
collection: 'viewers', // <- specify your collection, in your case it is a "viewers" collection.
options: '',
template: Template.vLegend
}],
};
}
For more information please read here.
Hope this helps!
Been some time since I last looked at Angularjs. I have a simple get that calls an ASP.NET Controller and returns a Json object - the get is triggered but nothing is getting populated on the view. The Json object shows in the browser, so it's purely a JS Angular thing. I know I am missing something simple, but I can't quite put my finger on it. If someone would be kind enough to show what I'm missing preferably with an example that would great. I haven't been able to find a simple example, that's similar.
Angularjs.
var ngCurrent = angular.module("ngCurrent", ['ngResource']);
var ctrCd;
// Declaring a Service
ngCurrent.factory("CurrentService", function ($resource) {
return {
data: $resource("/Current/Data/:id")
}
});
ngCurrent.controller("CurrentController", function ($scope, CurrentService) {
$scope.current = CurrentService.data.get({ "id": id}, isArray = false);
});
In the CSHTML View (Condensed but all relevant rows included)
<div ng-app="ngCurrent" class="row">
<div ng-controller="CurrentController" class="col-md-1"></div>
<div class="row">
<span class="col-sm-2">{{current.RecordName}}</span>
It runs triggers the "Get" from the controller but displays no data and $scope.current contains no object.
I have had a go at JSFiddling without success here it is http://jsfiddle.net/Mark_Dete/Lfy66re1/1/
(note the Json mocking is based on http://jsfiddle.net/ExpertSystem/6PYsq/)
You can return a promise from your service like:
return $http({
url: '/api/v1/service/',
method: "GET",
headers: {'X-API-TOKEN': api_key },
params: _params
})
Then use the promise callbacks on the http object in your controller (the one returned from your service)
$scope.getApiData = function(){
Service.getData($scope.api_key)
.then(function(_data) {
console.log(_data.data);
$scope.data_obj = _data.data;
});
here's an all in one version without the service abstraction but it should work for testing.
$scope.getApiData = function(){
$http({
url: '/api/v1/service/',
method: "GET",
headers: {'X-API-TOKEN': api_key },
params: _params
})
.then(function(_data) {
console.log(_data.data);
$scope.data_obj = _data.data;
});
Make sure you remember to inject the $http dependency!
I'm using the excellent fullcalendar by arshaw with Angular UI and right now I'm having a problem with eventSource objects in extended form not rendering when fetched as JSON feeds.
The data is fetched using the following code in the controller:
$scope.events = [
'/api/v1/users/104/events?format=cal&type=9',
'/api/v1/users/104/events?format=cal&type=10'
];
$scope.eventSources = $scope.events;
When the JSON feed returns an array with event objects it actually works:
// returned by - /api/v1/users/104/events?format=cal&type=9
[
{
url: "/#/events/86893",
start: "2013-03-15",
title: ": Event - 86893"
},
{
url: "/#/events/31348",
start: "2013-03-27T09:30Z",
title: "Event - 31348"
}
],
// returned by - /api/v1/users/104/events?format=cal&type=10
[
{
url: "/#/events/86899",
start: "2013-03-25",
title: ": Event - 86899"
},
{
url: "/#/events/31349",
start: "2013-03-17T09:30Z",
title: "Event - 31349"
}
]
However I would like to specify some options along with the event data, for example different colors for different JSON feeds. Hence I settled for the API to return the event source in its extended form . This is what it API returns.
// returned by - /api/v1/users/104/events?format=cal&type=9
{
events: [
{
url: "/#/events/86893",
start: "2013-03-15",
title: "Event - 86893"
},
{
url: "/#/events/31348",
start: "2013-03-27T09:30Z",
title: "Event - 31348"
}
],
color: "#ff9900",
allDayDefault: false,
ignoreTimezone: true
},
// returned by - /api/v1/users/104/events?format=cal&type=10
{
events: [
{
url: "/#/events/86899",
start: "2013-03-25",
title: "Event - 86899"
},
{
url: "/#/events/31349",
start: "2013-03-17T09:30Z",
title: "Event - 31349"
}
],
color: "#3366FF",
allDayDefault: false,
ignoreTimezone: true
}
Unfortunately this format isn't rendered when fetched as JSON. When fetching the extended format I changed the eventSources assignment somewhat to look like this:
$scope.eventSources = [ $scope.events ];
If I cut and paste the raw JSON response (with the event source in its extended form) from the API straight into the eventSources method it works. Isn't it possible to consume the event source in extended form when it is returned as a JSON feed?
Could it be that the eventSource being returned from the API is not where the extended form options should be used, but rather in the event functions used as the eventSource's.
The documentation states that the extended form should be used inside of the Json object used to call the API.
http://arshaw.com/fullcalendar/docs/event_data/events_json_feed/
If the API was too return the extra options for the events, then it would need to set each one individually.
Currently in this post, The only place I see where the extended options are called is from the returned api data.
I think this should be the other way around. And the calendar should know about the extended form before it even requests the data at all. This would mean the server will not need to return any extra options and the calendar will organize the event objects by feed and extended options.
If you could post a plunk, then we could nail this.