I am rewriting a javascript program that uses json files to one that uses xml files for the settings. The xml files that I have do not have the same structure as the json files and some of the json variables I intend to hard code into the program. I am thinking it would be easiest not recode all of the calls to the json data, so I am trying to create objects that look like the json data and have my own functions to load the xml data into the objects where needed.
Note I have never messed with json before. if you think there may be a better approach I would be happy to try it.
Simple json files I have figured out, just make a class that looks the same.
{
"logo": "yes",
"title": "Jordan Pond",
"author": "Matthew Petroff",
"license": 1,
"preview": "../examples/examplepano-preview.jpg",
}
turns into
function config(){
this.logo='yes';
this.title='Jordan Pond';
this.author='Matthew Petroff';
this.license='1';
this.preview='./examples/examplepano-preview.jpg';
}
config= new config();
alert(config.title);
Do that and all of the calls to the json stuff works the same as always. I am stumped on the more complicated json files such as
{
"default": {
"license": 0,
"logo": "no",
"author": "Kvtours.com",
"firstScene": "WilsonRiverFishingHole",
"title": "Wilson"
},
"scenes": {
"pond": {
"title": "Jordan Pond",
"preview": "../examples/examplepano-preview.jpg",
"panorama": "../examples/examplepano.jpg"
}
}
}
I would think that should convert to something like this.
function tourConfig(){
this.default= function() {
license= "0";
logo= "no";
author= "Kvtours.com";
firstScene= "pondCube";
title= "Wilson";
}
this.scenes= function(){
this.pondCube= function() {
this.title= "Jordan Pond (Cube)";
this.preview="examples/examplepano-preview.jpg";
this.panorama="../examples/examplepano.jpg";
}
}
}
tourConfig= new tourConfig();
alert(tourConfig.default.author);
That is not working. Any thoughts on how to get it to work?
You are confused on javascript closure.
I think what you want is as follow:
function tourConfig(){
var that = this;
this.default= function() {
that.license= "0";
that.logo= "no";
that.author= "Kvtours.com";
that.firstScene= "pondCube";
that.title= "Wilson";
}
// as well as scenes method
}
Related
I have a list of data in my JSON file. I am trying to output certain strings and arrays from my JSON file via my JS. How do I go on about this? All these files are saved on my desktop.
I've tried Xhttp code. But I think I need some server going on for that, and I don't have that. Also, I'm pretty sure this should be possible without having to use a server?
PS: the json file is named: movie.json
JSON CODE
{
"movie": {
"name": "drive",
"year": "2011",
"people": {
"actors": [
{
"name": "ryan gosling"
},
{
"name": "cary mulligan"
},
{
"name": "bryan cranston"
}
]
}
}
}
JS CODE
function preload() {
var movie = load.JSON("movie.json");
}
function(movie) {
var movie = JSON.parse(movie);
console.log(movie[0].name);
console.log(movie[0].year);
console.log(movie[0].actors);
}();
drive, 2011, ryan gosling, cary mulligan, bryan cranston
var movie;
var http = new XMLHttpRequest();
xhhtp.open( "GET", "movie.json", true);
xhttp.onreadystatechange = function () {
if(http.readyState == 4 && http.status == 200) {
movie = JSON.parse(http.responseText);
}
}
http.send();
console.log(movie[0].name);
console.log(movie[0].year);
console.log(movie[0].actors);
I do not know if the code above will help you. Using XMLHttpRequest will help you fetch the json file then you can parse and sort into array. Note: you do not need a server to use XMLHttpRequest, if you have text editor like VSCode you can us it to run live HTML codes then you can get the full link to the JSON file you want to parse e.g localhost:9000/movie.json
In my project, I need to create a questionnaire (a form). The questions are generated dynamically depending on a category, and are on a server, in a database.
To get the questions a REST API is used, so sending a request to /getquestions/1 returns a JSON having all the data needed for form generation.
The JSON looks like this:
{
"questions":[
{
"id":4,
"text":"Question1",
"type":"NUMBER",
"mandatory":true,
"visible":true
},
{
"id":5,
"text":"Dropdown type question",
"type":"DROPDOWN",
"mandatory":true,
"visible":true,
"values":[
{
"id":1,
"text":"Answer1",
"selected":false
},
{
"id":2,
"text":"Answer2",
"selected":false
}
]
},
{
"id":7,
"text":"Question 3 as Radio",
"type":"RADIO",
"mandatory":false,
"visible":false,
"values":[
{
"id":1,
"text":"Yes",
"selected":false
},
{
"id":2,
"text":"No",
"selected":false
}
],
"dependencies":{
"mark_visible":[
{
"question_id":5,
"operation":"=",
"value":2
}
],
"mark_mandatory":[
{
"question_id":5,
"operation":"=",
"value":2
},
{
"question_id":4,
"operation":"<=",
"value":5000
}
]
}
}
]
}
]
}
I have store and model for questions.
I think I need a store for values as well, to make it visible in a dropdown list, and another one for the dependencies too.
I just wondering, whether is it possible to fill all stores somehow without any explicite coding, using ext and model relations like hasMany and so.
I am basically looking for the best practice and fastest solution in Ext.js to create models and relations out of this JSON
any idea woud be really helpful.
To populate a model and its associations from JSON data you need to have it go through a reader class (e.g. Ext.data.JsonReader) where it will move down the 'tree' creating the associations.
If you are loading through a proxy this should happen automatically (as it uses a reader by default). If your JSON is coming from an AJAX call and you are creating the model instance with an Ext.create call then you need to do the reader bit yourself. Something like:
var data = [...];
var reader = Ext.create('Ext.data.JsonReader', {
model: 'MyModel'
});
var resultset = reader.readRecords(data);
console.log(resultset.getRecords()[0]); // logs first read record
I have a really bad-formated javascript object:
commits = {
commit: {
name: 'First commit'
},
commit: {
name: 'Second commit'
}
}
As you can see, each sub-object of commits object is called commit so it practically precludes an option to use for ... in ... or any other javascript loop (well, that's what i think but i'm a really poor JS programmer so i'm probably wrong). So, the question is, how can i iterate through that object?
Please have in mind that i can't use jQuery here and i can't rewrite that object
edit: that object is parsed from the following json:
{
"commits": {
"commit": {
"name": "First commit"
},
"commit": {
"name": "Second commit"
},
}
}
Considering the JSON posted in the github link you provided, there's not a lot you have to do.
The JSON string seems to be valid, except that it's missing a } at the end of the string. With that fixed, it parses just fine:
JSON.parse('{\n \"accountURL\": \"https://domain.com\",\n \"newCommitsCount\": \"1\",\n \"pushURL\":\"https://domain.com/project/64249/git/source/compare/revisions/0b6438955f2a5a7981fd25cfa5b48fe3fb4c888d,7771e638d1356a14d1dc46f3f5cfaab858370a5e\",\n \"unsubscribeURL\": \"https://domain.com:443/unsubscribe?token=receiverToken&type=COMMITS&projectId=64249\",\n \"invokerEmail\": \"email#email.com\",\n \"projectURL\": \"https://domain.com/project/64249\",\n \"projectId\": \"64249\",\n \"afterPushRevision\": \"7771e638d1356a14d1dc46f3f5cfaab858370a5e\",\n \"invokerId\": \"38074\",\n \"pushDate\": \"2014-02-11T15:26:36+0000\",\n \"beforePushRevision\": \"0b6438955f2a5a7981fd25cfa5b48fe3fb4c888d\",\n \"repositoryURL\": \"git_url\",\n \"subdomain\": \"subdomain\",\n \"domain\": \"domain\",\n \"branch\": \"develop\",\n \"invokerProfileURL\": \"url\",\n \"commitsCount\": \"1\",\n \"invokerSmallAvatarURL\": \"xx\",\n \"projectName\": \"NAME\",\n \"invoker\": \"Invoker Name.\",\n \"commits\": {\"commit\": {\n \"revision\": \"7771e638d1356a14d1dc46f3f5cfaab858370a5e\",\n \"commitMessage\": \"quickfix\",\n \"committerId\": \"38074\",\n \"committerEmail\": \"email\",\n \"committerName\": \"Name.\",\n \"commitDate\": \"2014-02-11T15:26:27+0000\",\n \"commitURL\": \"https://domain.com/project/64249/git/source/commit/develop/7771e638d1356a14d1dc46f3f5cfaab858370a5e\" }}}')
I've got a JSON file that looks like this.
{
"config": {
"setting1": 'blabla',
"setting2": 'blablabla'
},
"content": {
"title": "Title of an exercise.",
"author": "John Doe",
"describtion": "Exercise content."
},
"answers": [
{
"id": "1",
"content": "Dog",
"correct": true
},
{
"id": "2",
"content": "Fish",
"correct": false
}
]
}
Than, I create a Backbone View, combined from content model, and answers (which are randomly selected, but It's not most important now).
I've also got a config, which has settings that will determinate which view and collection methods to use.
It seems like a simple task, but as I'm new to Backbone, I'm wondering which is the best way to fetch JSON file, creating one model with url to JSON and than using parse and initialize creating another models and collections (with answers), or using $.getJSON method that will create exactly the models that I need?
I was trying using $.getJSON
$.getJSON(source, function(data) {
var contentModel = new ContentModel(data.content);
var contentView = new ExerciseView({ model: contentModel });
var answerCollection = new AnswersCollection();
_.each(data.answers, function(answer) {
answerCollection.add(answer);
});
var answersView = new AnswersView({collection: answerCollection});
$(destination).html( contentView.render().el );
$('.answers').append( answersView.el );
)};
But It doesn't seem very elegant solution, I know that this application needs good architecture, cause It will be developed with many other Views based on 'config'.
Hope you guys give me some suggestions, have a good day!
I think what you've done works fine and is correct. But you may need to refactor a little bit since "it will be developed with many other Views based on 'config'".
IMHO, the first thing you need to do is to handle failure in your getJson callback to make the process more robust.
Second, it is useful to create a Factory to generate your views because your logic is to generate different views based on the config data from server. So the factory maybe:
contentViewFactory.generate = function(data) {
var config = data.config;
....
var ActualContentView = SomeContentView;
var contentModel = new ContentModel(data.content);
return = new ActualContentView({ model: contentModel });
}
If your logic is simple, you can have a dict map from config to view class like:
var viewMaps = {
"exercise" : ExerciseView,
"other": SomeOtherView,
//....
}
And if every workflow has a AnswersView you can keep that in your getJSON callback. So maybe now your getJSON looks like this:
$.getJSON(source, function(data) {
// keep the config->view logic in the factory
var contentView = contentViewFactory.generate(data);
var answerCollection = new AnswersCollection();
_.each(data.answers, function(answer) {
answerCollection.add(answer);
});
var answersView = new AnswersView({collection: answerCollection});
$(destination).html( contentView.render().el );
$('.answers').append( answersView.el );
})
.fail(){
//some failure handling
};
Furthermore, if you have common logics in you "ContentView"s, it's natural that you can have a "BaseContentView" or "ContentViewMixin" to extract the common logic and use extends to make your code more OO:
Backbone.View.extend(_.extend({}, ContentViewMixin, {
//.....
}
So if someone is trying to add a new ContentView, he/she just needs to add some code in the factory to make the new View be generated by config. Then extends the ContentViewMixin to implement the new View.
I'm using backbone and handlebars for templating and i'm new to this.
My current json is in the below format and the code works fine.
[
{
"id": "10",
"info": {
"name": "data10"
}
},
{
"id": "11",
"info": {
"name": "data11"
}
}
]
But when i change my json structure to something like shown below i'm having difficulty in getting things to be populated.
{
"total_count": "10",
"dataElements": [
{
"id": "10",
"info": {
"name": "data10"
}
},
{
"id": "11",
"info": {
"name": "data11"
}
}
]
}
How can i populate name, info and total_count keeping the current code structure ?
JSFiddle : http://jsfiddle.net/KTj2K/1/
Any help really appriciated.
A few things that you need to do in order for this to work.
Replace Backbone's core 'reset' on your collection with a custom one that understands the data you are passing to it. For example:
reset: function (data) {
this.totalCount = data.total_count;
Backbone.Collection.prototype.reset.call(this, data.dataElements);
}
Now when you reset your collection, it will pull the total_count out of the object you are resetting it with, and use Backbone's core reset with the dataElement array. Keep in mind you may have to do a similar thing with 'parse' if you're intending on pulling this from the server.
I'd recommend that (if your example looks anything like the real code you're working with) you reset your collection before getting to rendering.
var dataCollectionList = new dataCollection();
dataCollectionList.reset(jsonData);
var App = new AppView({model : dataCollectionList});
Now in your view's "render" method you can grab the 'totalCount' property off the collection -
render : function() {
//Should spit the total count into the element, just as an example
this.$el.append(this.model.totalCount);
//or console.log it
console.log(this.model.totalCount);
return this;
}
Voila. Side note - as someone who works with Backbone a lot, it drives me nuts when people set an attribute of something like "model" (i.e. peopleModel, itemModel, etc) and it ends up being a backbone collection. It's much clearer to name it after what it is - though some MVC purists may disagree a bit.
Also, in this code block:
_.each(this.model.models, function (myData) {
$(this.el).append(new ItemView({model:myData}).render().el);
}, this);
You don't need to do _.each(this.model.models.......). Since you're working with a collection, the collection has a built in 'each' method.
this.model.each(function (myData) { ..... } , this);
Quite a bit cleaner.