How to convert Backbone fetched object to proper Handlebars JSON Object? - json

Currently I have an issue with getting back a proper JSON object I'm fetching with Backbone fetch() and putting it into a Handlebars template.
See below my code, I have made a ugly workaround for now to test my Backend API
When converting to JSON with *.toJSON(), it just adds an extra object in-between and I don't need this extra object
Object [0]
--> books
----> Object [0]
------> Array of book
--------> book
--------> cities
JSON
{
"books": [
{
"book": 00001,
"cities": [
"TEST"
]
},
{
"book": 00002,
"cities": [
"TEST"
]
},
{
"book": 00003,
"cities": [
"TEST"
]
}
],
"more": true
}
JavaScript
var Book = Backbone.Model.extend({
default: {
book: 0,
cities: ["TEST1", "TEST2", "TEST3"]
},
url: function () {
return ".list.json";
}
});
var Books = Backbone.Collection.extend({
model: Book,
url: ".list.json"
});
var BooksView = Backbone.View.extend({
initialize: function(){
_.bindAll(this, 'render');
this.collection = new Books();
this.collection.fetch();
this.source = $('.e-books-template').html();
// Use an extern template
this.template = Handlebars.compile(this.source);
var self = this;
this.collection.fetch({
success: function () {
self.render();
},
error: function () {
console.log("ERROR IN BooksView");
}
});
},
render: function() {
var collect = JSON.stringify(this.collection);
collect = collect.slice(1, -1);
var html = this.template($.parseJSON(collect));
this.$el.html(html);
}
});
var booksView = new BooksView({ });
$(document).ready(function(){
booksView.$el = $('.e-books-content');
});

A Backbone collection expects an array of models but your JSON provides an object with the array under a books key. Parse the server response to format the data :
var Books = Backbone.Collection.extend({
model: Book,
url: ".list.json",
parse: function(data) {
return data.books;
}
});
Pass your data to your template via http://backbonejs.org/#Collection-toJSON ,
// directly as an array in your template
var html = this.template(this.collection.toJSON());
// under a books key
var html = this.template({
books: this.collection.toJSON()
});
And a demo http://jsfiddle.net/nikoshr/8jdb13jg/

Related

Format HERE Map API JSON Response

I am experiencing an issue formatting the JSON response from the HERE Map API for an isoline. The full HERE API JSON response is shown below and contains Lat/Long coordinates for a line as shown below.
{
"response": {
"metaInfo": {
"timestamp": "2017-03-03T23:40:34Z",
"mapVersion": "8.30.68.151",
"moduleVersion": "7.2.201709-111134",
"interfaceVersion": "2.6.29"
},
"center": {
"latitude": 34.603565,
"longitude": -98.3959
},
"isoline": [
{
"range": 300,
"component": [
{
"id": 0,
"shape": [
"34.6096802,-98.4147549",
"34.6096802,-98.4141541",
"34.6098518,-98.4136391",
"34.6101952,-98.4132957",
"34.6103668,-98.4127808",
"34.6101952,-98.4122658",
"34.6098518,-98.4119225",
"34.6098518,-98.4115791",
"34.6101952,-98.4112358",
"34.5998955,-98.4115791",
"34.6002388,-98.4126091",
"34.6005821,-98.4129524",
"34.6009254,-98.4139824",
"34.6019554,-98.4143257",
"34.6022987,-98.4153557",
....
"34.6081352,-98.4129524",
"34.6083069,-98.4134674",
"34.6083069,-98.4148407",
"34.6084785,-98.4153557",
"34.6089935,-98.4155273",
"34.6095085,-98.4154415",
"34.6096802,-98.415184",
"34.6096802,-98.4147549"
]
}
]
}
],
"start": {
"linkId": "+888249498",
"mappedPosition": {
"latitude": 34.6034836,
"longitude": -98.3959009
},
"originalPosition": {
"latitude": 34.603565,
"longitude": -98.3959
}
}
}
}
I am mapping the isoline data in Leaflet as a polygon. I can do it manually like this, and all works well.
var polygon = L.polygon([
[34.6343994, -98.7664032],
[34.6357727, -98.76297],
[34.6385193, -98.7602234],
[34.6398926, -98.7561035],
[34.6385193, -98.7519836],
[34.6357727, -98.7492371],
[34.6357727, -98.7464905],
.....
[34.6302795, -98.7712097],
[34.6330261, -98.7718964],
[34.6343994, -98.7698364],
[34.6343994, -98.7664032]
]
).addTo(map);
Am now trying to automate it but cannot get the json output into a compatible format for Leaflet. I can make the API call, capture the JSON response, and extract the array of lat/long coordinates using the following code:
function getJson(url) {
return JSON.parse($.ajax({
type: 'GET',
data: '',
url: url,
dataType: 'json',
global: false,
async: false,
success: function (data) {
return data;
}
}).responseText);
}
var myJsonObj = getJson('https://isoline.route.cit.api.here.com/routing/7.2/calculateisoline.json?mode=fastest;car;traffic:disabled&jsonAttributes=1&rangetype=time&start=34.603565,-98.3959&app_id=id&app_code=codeg&range=1800');
var isoline = myJsonObj.response.isoline[0].component[0].shape;
The variable isoline looks like this (an array of lat/long coordinate pairs) but I cannot get them into an array of arrays as needed for Leaflet.
[
"34.6096802,-98.4147549",
"34.6096802,-98.4141541",
"34.6098518,-98.4136391",
"34.6101952,-98.4132957",
"34.6103668,-98.4127808",
"34.6101952,-98.4122658",
"34.6098518,-98.4119225",
"34.6098518,-98.4115791",
"34.6101952,-98.4112358",
"34.5998955,-98.4115791",
"34.6002388,-98.4126091",
"34.6005821,-98.4129524",
"34.6009254,-98.4139824",
"34.6019554,-98.4143257",
"34.6022987,-98.4153557",
....
"34.6081352,-98.4129524",
"34.6083069,-98.4134674",
"34.6083069,-98.4148407",
"34.6084785,-98.4153557",
"34.6089935,-98.4155273",
"34.6095085,-98.4154415",
"34.6096802,-98.415184",
"34.6096802,-98.4147549"
]
Would appreciate any help in reformatting the coordinates to look like this
[
[34.6343994, -98.7664032],
[34.6357727, -98.76297],
[34.6385193, -98.7602234],
[34.6398926, -98.7561035],
[34.6385193, -98.7519836],
[34.6357727, -98.7492371],
[34.6357727, -98.7464905],
.....
[34.6302795, -98.7712097],
[34.6330261, -98.7718964],
[34.6343994, -98.7698364],
[34.6343994, -98.7664032]
]
It may be that there is a better way of putting the data in Leaflet as well, but Polygon and Polyline are the only methods I can find and they require the coordinates in an array of arrays.
You need to iterate over each element and split, forming an array.
Like this, (ES6 way)
const newArray = array.map(a => a.split(',').map(Number));
or (Non ES6 way)
var newArray = [];
array.forEach(function (a){ newArray.push(a.split(',').map(Number)); });
So your final code should look like this,
function getJson(url) {
return JSON.parse($.ajax({
type: 'GET',
data: '',
url: url,
dataType: 'json',
global: false,
async: false,
success: function (data) {
return data;
}
}).responseText);
}
function parseJSONForPolygon(rawJsonArray) {
var newArray = [];
rawJsonArray.forEach(function (a) { newArray.push(a.split(',').map(Number)); });
return newArray;
};
var myJsonObj = getJson('https://isoline.route.cit.api.here.com/routing/7.2/calculateisoline.json?mode=fastest;car;traffic:disabled&jsonAttributes=1&rangetype=time&start=34.603565,-98.3959&app_id=id&app_code=codeg&range=1800');
var isoline = parseJSONForPolygon(myJsonObj.response.isoline[0].component[0].shape);
.map(Number) credit goes to
https://stackoverflow.com/a/15677905/923426
let polygonArray = [];
data.response.isoline.component.shape.forEach((elm) => {
polygonArray.push(elm.split(','));
})
now your polygonArray will be acceptable by leaflet

Can't assign json data from controller to data in HighStock

I'm trying to load json data from controller Jsonresult in MVC 4 but it doesn't seems to work in HighStock. The data was serialized and the alert it popping up and displaying the data. I don't know why the chart is not rendering. But it is working when i create a variable like var data = [1,2] in the javascript function.
<script type="text/javascript">
$(function () {
$.getJSON('GetData', function (data) {
alert(data);
var data1 = [1, 2];
alert(data1);
// Create the chart
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 1
},
title: {
text: 'AAPL Stock Price'
},
series: [{
name: 'AAPL',
data: data,
tooltip: {
valueDecimals: 2
}
}]
});
});
});
[HttpGet]
public JsonResult GetData()
{
string sample = "[1,2]";
var jss = new JavaScriptSerializer();
var output = jss.Serialize( sample );
return Json( output, JsonRequestBehavior.AllowGet );
}

Backbone toJSON not rending

I am a complete n00b to Backbone.js, and have only been working with it for a few days. I am attempting to fetch JSON data to populate the model, and in this scenario I have two models that I need to generate. Here is the sample JSON I have been working with:
JSON
{
"status": "200",
"total": "2",
"items":
[{
"id": "1",
"name": "Here is another name",
"label": "Label for test",
"description": "A description for more information.",
"dataAdded": "123456789",
"lastModified": "987654321"
},
{
"id": "2",
"name": "Name of item",
"label": "Test Label",
"description": "This is just a long description.",
"dataAdded": "147258369",
"lastModified": "963852741"
}]
}
Backbone JS
// MODEL
var Service = Backbone.Model.extend({
defaults: {
id: '',
name: '',
label: '',
description: '',
dateAdded: '',
dateModified: ''
}
});
var service = new Service();
// COLLECTION
var ServiceList = Backbone.Collection.extend({
model: Service,
url: "./api/service.php",
parse: function(response) {
return response.items;
}
});
//
var serviceList = new ServiceList();
var jqXHR = serviceList.fetch({
success: function() {
console.log("Working!");
console.log(serviceList.length);
},
error: function() {
console.log("Failed to fetch!");
}
});
// VIEW for each Model
var ServiceView = Backbone.View.extend({
el: $('.widget-content'),
tagName: 'div',
template: _.template($('#service-template').html()),
initialize: function() {
this.collection.bind("reset", this.render, this);
},
render: function() {
console.log(this.collection);
this.$el.html('');
var self = this;
this.collection.each(function(model) {
self.$el.append(self.template(model.toJSON()));
});
return this;
}
});
//
var serviceView = new ServiceView({
collection: serviceList
});
console.log(serviceView.render().el);
html
<div class="widget-content">
<!-- Template -->
<script type="text/template" id="service-template">
<div><%= name %></div>
</script>
</div>
When I console log the serviceList.length I get the value 2, so I believe the JSON object is fetched successfully. I also get the "Working!" response for success too. However, in the view I am showing an empty object, which gives me an empty model.
I am still trying to understand the best way to do this too. Maybe I should be using collections for the "items" and then mapping over the collection for each model data? What am I doing wrong? Any advice or help is greatly appreciated.
I can see two problems. First, you want to remove serviceList.reset(list). Your collection should be populated automatically by the call to fetch. (In any case the return value of fetch is not the data result from the server, it is the "jqXHR" object).
var serviceList = new ServiceList();
var jqXHR = serviceList.fetch({
success: function(collection, response) {
console.log("Working!");
// this is the asynchronous callback, where "serviceList" should have data
console.log(serviceList.length);
console.log("Collection populated: " + JSON.stringify(collection.toJSON()));
},
error: function() {
console.log("Failed to fetch!");
}
});
// here, "serviceList" will not be populated yet
Second, you probably want to pass the serviceList instance into the view as its "collection". As it is, you're passing an empty model instance into the view.
var serviceView = new ServiceView({
collection: serviceList
});
And for the view, render using the collection:
var ServiceView = Backbone.View.extend({
// ...
initialize: function() {
// render when the collection is reset
this.collection.bind("reset", this.render, this);
},
render: function() {
console.log("Collection rendering: " + JSON.stringify(this.collection.toJSON()));
// start by clearing the view
this.$el.html('');
// loop through the collection and render each model
var self = this;
this.collection.each(function(model) {
self.$el.append(self.template(model.toJSON()));
});
return this;
}
});
Here's a Fiddle demo.
The call serviceList.fetch is made asynchronously, so when you try console.log(serviceList.length); the server has not yet send it's response that's why you get the the value 1, try this :
var list = serviceList.fetch({
success: function() {
console.log(serviceList.length);
console.log("Working!");
},
error: function() {
console.log("Failed to fetch!");
}
});

CompoundJS :: How to create the schema to reflect a semi complex JSON object?

If my schema is as follows:
var Configuration = describe('Configuration', function () {
property('name', String);
set('restPath', pathTo.configurations);
});
var Webservice = describe('Webservice', function () {
property('wsid', String);
property('url', String);
});
Configuration.hasMany(Webservice, { as: 'webservices', foreignKey: 'cid'});
and that reflects data like so:
var configurationJson = {
"name": "SafeHouseConfiguration2",
"webServices": [
{"wsid": "mainSectionWs", "url":"/apiAccess/getMainSection" },
{"wsid": "servicesSectionWs", "url":"/apiAccess/getServiceSection" }
]
};
shouldn’t I be able to seed mongoDB with the following:
var configSeed = configurationJson;
Configuration.create(configSeed, function (err, configuration) {
)};
which would create the following tables with data from the json object:
Configuration
Webservice
Since this did not work as I had expected, my seed file ended up as the following:
/db/seeds/development/Configuration.js
var configurationJson = {
"name": "SafeHouseConfiguration2",
"webServices": [
{"wsid": "mainSectionWs", "url":"/apiAccess/getMainSection" },
{"wsid": "servicesSectionWs", "url":"/apiAccess/getServiceSection" }
]
};
Configuration.create(configurationJson, function (err, configuration) {
//Webservices config
var webservicesConfig = configSeed.webServices;
webservicesConfig.forEach(function(wsConfig){
configuration.webservices.create(wsConfig, function(err){
});
});

How to create JSON object using jQuery

I have a JSON object in below format:
temp:[
{
test:'test 1',
testData: [
{testName: 'do',testId:''}
],
testRcd:'value'
},
{
test:'test 2',
testData: [
{testName: 'do1',testId:''}
],
testRcd:'value'
}
],
How can i create JSON object in jquery for above format. I want to create a dynamic JSON object.
Just put your data into an Object like this:
var myObject = new Object();
myObject.name = "John";
myObject.age = 12;
myObject.pets = ["cat", "dog"];
Afterwards stringify it via:
var myString = JSON.stringify(myObject);
You don't need jQuery for this. It's pure JS.
A "JSON object" doesn't make sense : JSON is an exchange format based on the structure of Javascript object declaration.
If you want to convert your javascript object to a json string, use JSON.stringify(yourObject);
If you want to create a javascript object, simply do it like this :
var yourObject = {
test:'test 1',
testData: [
{testName: 'do',testId:''}
],
testRcd:'value'
};
I believe he is asking to write the new json to a directory. You will need some Javascript and PHP. So, to piggy back off the other answers:
script.js
var yourObject = {
test:'test 1',
testData: [
{testName: 'do',testId:''}
],
testRcd:'value'
};
var myString = 'newData='+JSON.stringify(yourObject); //converts json to string and prepends the POST variable name
$.ajax({
type: "POST",
url: "buildJson.php", //the name and location of your php file
data: myString, //add the converted json string to a document.
success: function() {alert('sucess');} //just to make sure it got to this point.
});
return false; //prevents the page from reloading. this helps if you want to bind this whole process to a click event.
buildJson.php
<?php
$file = "data.json"; //name and location of json file. if the file doesn't exist, it will be created with this name
$fh = fopen($file, 'a'); //'a' will append the data to the end of the file. there are other arguemnts for fopen that might help you a little more. google 'fopen php'.
$new_data = $_POST["newData"]; //put POST data from ajax request in a variable
fwrite($fh, $new_data); //write the data with fwrite
fclose($fh); //close the dile
?>
How to get append input field value as json like
temp:[
{
test:'test 1',
testData: [
{testName: 'do',testId:''}
],
testRcd:'value'
},
{
test:'test 2',
testData: [
{testName: 'do1',testId:''}
],
testRcd:'value'
}
],
Nested JSON object
var data = {
view:{
type: 'success', note:'Updated successfully',
},
};
You can parse this data.view.type and data.view.note
JSON Object and inside Array
var data = {
view: [
{type: 'success', note:'updated successfully'}
],
};
You can parse this data.view[0].type and data.view[0].note
var model = {"Id": "xx", "Name":"Ravi"};
$.ajax({ url: 'test/set',
type: "POST",
data: model,
success: function (res) {
if (res != null) {
alert("done.");
}
},
error: function (res) {
}
});