aphex
aphex

Reputation: 1187

Backbone model .toJSON() doesn't work after .fetch()

Good day! I need to render a model's attributes to JSON so I can pass them into a template.

Model:

var UserInfo = Backbone.Model.extend({
url: appConfig.baseURL + "users/",
});

Template:

<script type="text/html" class="template" id="profile-form">
    <h2 class="ui-li-heading"><%= username %></h2>
    <p class="ui-li-desc"><strong><%= phone %></strong></p>
</script>

View:

var ProfilePageView = Backbone.View.extend({
    events: {
        'click #edit': "edit"
    },

    initialize: function () {
        this.template = $.tpl['profile-form'];

        var user = new UserInfo()
        user.fetch({
            data: $.param({email: localStorage.getItem('user_email')}),
            type: 'POST'
        });

        console.log(user) //returns correct object with attrs
        console.log(user.toJSON()) //returns empty object
    },

    render: function (eventName) {
        $(this.el).html(this.template());
    },

    edit: function () {
        window.workspace.navigate('#account/edit', { trigger: true});
    }
});

When i put in console something like this, user.toJSON() returns correct data

var user = new UserInfo();
user.fetch({
        data: $.param({email: localStorage.getItem('user_email')}),
        type: 'POST'
});

But when i put it to my view, its returns Object {}. Where is a mistake or tell me how can differently pass to the template data received from the server in json format? Thanks!

Upvotes: 0

Views: 670

Answers (1)

RustyToms
RustyToms

Reputation: 7820

You appear to have two problems. fetch is asyncronous, so you need to use a callback to use the information. But first, an explanation about toJSON. .toJSON() doesn't actually return a JSON string, it returns an object that is what you want JSON to stringify. This allows you to modify the toJSON method to customize what attributes will be taken from your model or collection and added to the JSON string representation of your model. Here is a quotation from the Backbone.js docs:

toJSON collection.toJSON([options])

Return a shallow copy of the model's attributes for JSON stringification. This can be used for persistence, serialization, or for augmentation before being sent to the server. The name of this method is a bit confusing, as it doesn't actually return a JSON string — but I'm afraid that it's the way that the JavaScript API for JSON.stringify works.

So you should replace this line in your code

console.log(user.toJSON())

with this one

console.log(JSON.stringify(user))

The object that you saw was returned by toJSON will then be turned into JSON.

Now, even after you do that, it won't work properly, because you will execute the console.log before you get the data for your model from fetch. fetch is asynchronous, so you need to call any code you want to be executed after the fetch is done in the success callback:

    user.fetch({
        data: $.param({email: localStorage.getItem('user_email')}),
        type: 'POST',
        success: function(){
            console.log(user);
            console.log(JSON.stringify(user));
        }
    });

Upvotes: 1

Related Questions