Import json in backbone View - javascript

I'm new to backbone, and I'm still getting used to the flow of everything.. What I'm trying to do is import data.json file in my Model and make use of it in my view...
data.json
[
{ id: "001", student: "Mark" },
{ id: "002", student: "Sally" },
{ id: "003", student: "Harold" }
]
assets/data.js (model)
var DataModel = Backbone.Model.extend({
url: 'assets/data.json',
initialize: function() {
// this logs properly
console.log('this initializes');
}
})
data_view.js
var Students = Backbone.View.extend({
initialize: function() {
var data = new DataModel();
data.fetch();
// doesn't return json
console.log(data);
}
})
data logs like so...
v __proto__: Backbone.Model
> constructor: ()
> initialize: ()
url: "assets/data.json"
> __proto__: Object
All of my imports are correct, but why isn't my json loading within my view? What am I doing wrong? (I've tried making a collection, but that had the same effect; no json to be found)

Because fetch is using jQuery Ajax, so it's async. If you log data immediately after calling fetch, the data is not pull from server. You should do as follow:
data.fetch({
success: function(model, response, options) {
console.log(model);
},
error: function() {
}
});
Link reference: http://backbonejs.org/#Model-fetch

With using JQuery:
var DataModel = new DataModel();
$.when(DataModel.fetch()).then(function() {
var students = new Students({model: DataModel });
});

Related

got property undefined when fetching data in ajax using vue.js

I have got a undefined when I alert the param fetching from ajax using vue.js, here is my code.
test.json return:
[
{isActive: false,name: test}
]
js:
new Vue({
el: '#viewport',
data: {
test_data: []
},
mounted: function () {
this.fetchTestData();
},
methods: {
fetchTestData: function () {
$.get(test.json, function (data) {
this.test_data = data;
alert(this.test_data.isActive);
});
}
}
});
I am beginner of vue.js, hope have a reply, thanks.
If you are fetching this data from that test.json file,
first it need to be like that because that's not validate json:
[
{
"isActive": false,
"name": "test"
}
]
and you need to use bind because this not referring to the Vue instance
fetchTestData: function () {
$.get('test.json', function (data) {
this.test_data = data;
alert(this.test_data[0].isActive);
}.bind(this));
}
and accessing the data like that this.test_data[0].isActive because it's an array

Model rendering inside view: toJSON is not a function

I have added a model attribut inside a view like so:
app.ActorView = Backbone.View.extend({
modelImg:'', ....
I'm skipping to the rendering part as everything else is ok:
render: function () {this.$el.html(this.template({
modImg: this.modelImg.toJSON(),
mod: this.model.toJSON(),
movies: this.collection.toJSON()}
Every model in the view (model, collection and modelimg) is correctly fetched in the rooter part of my project:
modActor.fetch().done(function () {
modActorMovies.fetch().done(function () {
modImgActor.fetch().done(function () {
var actorView = new app.ActorView({
modelImg: modImgActor,<--problematic model
model: modActor,
collection: modActorMovies
});
My modImgActor definition is the following:
app.ActorImg= Backbone.Model.extend({
url: "http://umovie.herokuapp.com/unsecure/actors/272994458/movies",
parse: function (response) {
return response.results[0];
}
});
The problem is when I use the toJson() function on the modelImg. There is the following error: this.modelImg.toJSON is not a function
Can it be how the model is defined with its url?
modImg is not a standard option for Backbone.View. So backbone will just ignore it.
You have to manually handle the custom properties that you pass along with the options.
So you're view definition should be
app.ActorView = Backbone.View.extend({
initialize: function(options){
this.modelImg = options.modelImg;
}
}):

Backbone.js collection.create function doesn't return updated model with wait: true

In using Backbone.js with Laravel 4, I am inserting into the database using this.collection.create() with the wait: true option. It inserts into the database alright, but it doesn't update the model if wait: true is set. So if I try output the collection again, it's not updated even though trying a success callback function returned a value and the POST request comes back positive.
The app is a contact managing system.
This is my model for a contact:
App.Models.Contacts = Backbone.Model.extend({
});
This is my View for adding a contact
App.Views.AddContact = Backbone.View.extend({
el: '#addContact',
events: {
'submit': 'addContact',
},
initialize: function() { // cache values
this.first_name = $('#first_name');
this.last_name = $('#last_name');
this.email_address = $('#email_address');
this.description = $('#description');
},
addContact: function(e) {
e.preventDefault();
this.collection = this.collection.create({
first_name: this.first_name.val(),
last_name: this.last_name.val(),
email_address: this.email_address.val(),
description: this.description.val(),
}, { wait: true });
},
});
And this is the collection:
App.Collections.Contacts = Backbone.Collection.extend({
model: App.Models.Contacts,
url: '/projects/gamesapp/public/contacts',
});
And this is the script on the page that puts all this into action:
<script>
new App.Router;
Backbone.history.start();
App.contacts = new App.Collections.Contacts;
App.contacts.fetch().then(function() {
new App.Views.App({ collection: App.contacts });
});
</script>
What can I do to get this working? I want create in the view to update the model locally as well, which it doesnt seem to.
Thanks!
The problem was not in the js or backbone code, it was in the Laravel code I wrote.
It seemed that the POST returned a positive response and all, but the problem was in my controller's store method, you have to return the create() function from the store() function!!!, to make it clear:
public function store()
{
$input = Input::all();
return Contact::create(array( // YOU HAVE TO RETURN SOMETHING
'first_name' => $input['first_name'],
'last_name' => $input['last_name'],
'email_address' => $input['email_address'],
'description' => $input['description'],
));
}
My problem was ocurring because I wasn't returning it, just calling the Contact::create() function... (Contact is the Laravel Model)

Fetch collection only one time

i've a userlist made by a fetch from parse.com and rendered by view.Once people click on item list i've insert in url the objectid. In router i've made a function "home" that make fetch from collection and call view to render.The function "userdetails" catch objectid previous insert by view in url and use it to make a get from collection. The problem is:how can i pass the collection to this function userdetails?I don't want make another fetch.
home: function() {
var self=this;
console.log("inrouterhome");
var utenti = new Usercollection();
utenti.fetch({
success: function(object) {
var page=new Homelistuser({model:object});
self.changePage(page);
},
error: function(amici, error) {
// The collection could not be retrieved.
}
});
},
userDetails: function (objectId) {
HERE I WANNA USE OBJECTID TO MAKE A GET FROM COLLECTION FETCHED IN HOME
},
It looks like it is probably a scoping issue. Try this
var Models = {};
var AppRouter = Backbone.Router.extend({
home: function() {
var self=this;
console.log("inrouterhome");
Models.utenti = new Usercollection();
Models.utenti.fetch({
success: function(object) {
var page=new Homelistuser({model:object});
self.changePage(page);
},
error: function(amici, error) {
// The collection could not be retrieved.
}
});
},
userDetails: function (objectId) {
//Models.utenti should exist as long as home came first,
// may want to write a condition that check to see if it exists and if not do fetch.
}
});
As #abritez mentioned this is probably a scoping problem i.e. the userDetails method doesn't have access to the instantiated collection. #abritez's solution resolves this but if the user refreshes the page or accesses the route directly the collection will not be loaded.
If the collection is used between both routes consider fetching it at run time and using a listener for when it's ready:
var Models = {};
Models.utenti = new Usercollection();
Models.utenti.fetch();
var AppRouter = Backbone.Router.extend({
home: function() {
var utentiLoaded = function(object) {
var page = new Homelistuser({model:object});
this.changePage(page);
}
this.listenTo(Models.utenti, 'reset', utentiLoaded);
this.listenTo(Models.utenti, 'error', function(amici, error) {
// The collection could not be retrieved.
});
if (Models.utenti.any()) {
utentiLoaded(Models.utenti);
}
},
userDetails: function(objectId) {
var utentiLoaded = function(object) {
}
this.listenTo(Models.utenti, 'reset', utentiLoaded);
this.listenTo(Models.utenti, 'error', function(amici, error) {
// The collection could not be retrieved.
});
if (Models.utenti.any()) {
utentiLoaded(Models.utenti);
}
}
});

Nested Model in Backbone.js

I want to map JSON having hierarchical structure onto Model. I can map the data at a top hierarchy onto Model. However, I can't map it onto Model which nested the element which I nested.
JSON
{
"attr1":"data1",
"chi1": {
"attr1":"chi1_data"
},
"list1":[
{"name":"name1"},
{"name":"name2"}
]
}
JavaScript
var Child2 = Backbone.Model.extend({
fun1:function() {
alert("this is Child2");
}
});
var List1 = Backbone.Collection.extend({
url: "list1",
model: Child2,
fun1:function() {
alert("this is List1");
}
});
var Child1 = Backbone.Model.extend({
});
var Root1 = Backbone.Model.extend({
url: "sample.json",
defaults : {
list1 : new List1,
chi1 : new Child1,
}
});
var View1 = Backbone.View.extend({
el: "#friends",
events: {
"click button": "sample"
},
initialize: function() {
this.root1 = new Root1();
},
sample: function() {
this.root1.fetch({
success: function(model) {
// this is success
alert(model.get("attr1"));
// this is error
alert(model.get("list1").fun1());
// this is error too.
model.get("list1").each(function(attr) {
alert(attr.fun1());
});
},
error: function(model, res) {
alert("error: " + res.status);
}
});
},
});
You might want to take a look at this plugin.
http://documentup.com/afeld/backbone-nested/
Might not be exactly what you want, but it could at least point you in the right direction.
The other thing you can do is override the parse method on your model...
parse: function(resp){
// And setup the model using the raw resp
// The resp data is your json from the server and will
// be used to setup the model. So overriding parse, you can
// setup the model exactly they way you want.
return resp;
}
thank you jcreamer.
backbone-nested plugin seems to be different from what I want to do.
I can realize the nest of the model. In using parse function.
// it is able to get "chi1_data"
new Child2(JSON.parse(JSON.stringify(resp["chi1"]))).get("attr1")
// it is able to get "name2"
new Child2(JSON.parse(JSON.stringify(new List1(JSON.parse(JSON.stringify(resp["list1"]))).get(2)))).get("name")
I found Backbone-relational plug in. I will try this
https://github.com/PaulUithol/Backbone-relational

Categories

Resources