AlexNikolaev94
AlexNikolaev94

Reputation: 1209

Cannot get data from json-server

I'm making a little project in Backbone.js and I'm running a json-server package to populate it wih some data. I've made a db.json file with data and ran json-server --watch db.json, it started and runs perfectly on localhost:3000. In my Backbone app I have this:

// app/javascripts/collections/resumes.js

define(['backbone', 'models/resume'], function (Backbone, Resume) {
    var ResumesCollection = Backbone.Collection.extend({
        model: Resume,
        url: 'http://localhost:3000/resumes'
    });
    return ResumesCollection;
});

// app/javascripts/views/resumes/resume.js

define(['backbone', 'jquery'], function (Backbone, $) {
    var ResumeView = Backbone.View.extend({
        tagName: 'article',
        render: function () {
            this.$el.html(this.model.get("firstName"));
            return this;
        }
    });
    return ResumeView;
});

// app/javascripts/views/resumes/index.js

define(['backbone', 'views/resumes/resume'], function (Backbone, ResumeView) {
    var ResumesList = Backbone.View.extend({
        tagName: 'section',
        initialize: function() {
            this.collection.fetch();
        },
        render: function() {
            var resumesView = this.collection.map(function (cv) {
                return new ResumeView({model: cv}).render().el;
            });
            this.$el.html(resumesView);
            return this;
        }
    });
    return ResumeList;
});

this is my app/router.js:

define(['backbone',
        'collections/resumes',
        'views/resumes/resume',
        'views/resumes/index'], 
function (Backbone, ResumesCollection, ResumeView, ResumeList) {
    var AppRouter = Backbone.Router.extend({
        routes: {
            'resumes': 'showAll'
        },
        showAll: function () {
            this.ResumeList.render();
        }
    });
    return AppRouter;
});

and in app/javascripts/main.js I have this:

require.config({
    shim: {
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: [
                'underscore',
                'jquery'
            ],
            exports: 'Backbone'
        }
    },

    paths: {
        jquery: '../node_modules/jquery/dist/jquery',
        underscore: '../node_modules/underscore/underscore',
        backbone: '../node_modules/backbone/backbone'
    }
});

require(['backbone',
         'jquery',
         'router'
], function (Backbone, $, AppRouter) {
    var Router = new AppRouter();
    Backbone.history.start({
        pushState: true,
        root: '/'
    });
});

Also I use Gulp to run a development server on localhost:8080 via gulp-connect and gulp-livereload. But when I navigate to localhost:8080/resumes, it returns me Cannot GET /resumes, though there's no errors in console. What am I doing wrong?+

Upvotes: 2

Views: 2700

Answers (1)

Emile Bergeron
Emile Bergeron

Reputation: 17430

With what's provided, we can't pinpoint the exact problem and cause, but let me try to help anyway.

I tried json-server and started it with the following db.json:

{
    "posts": [{
        "id": 1,
        "title": "json-server",
        "author": "typicode"
    }, {
        "id": 2,
        "title": "This is a test",
        "author": "Emile Bergeron"
    }]
}

Then I made the simplest collection to use it.

var PostCollection = Backbone.Collection.extend({
    url: "http://localhost:3000/posts"
});

var posts = new PostCollection();
posts.fetch({
    success: function(){
        console.log(posts.pluck('title'));
    }
});

And in my console, I can see:

["json-server", "This is a test"]

Using it was surprisingly straightforward! So the problem is elsewhere. Maybe show us the full request (raw data).


Fetching a collection

this.collection.fetch(); // this is enough

There's no need to pass { data: { fetch: true, type:"get" } } as it is the default behavior anyway.

Chaining function calls

The following line inside ResumeList will fail:

return new ResumeView({model: cv}).render().el;

This is because the render function of the ResumeView doesn't return this.


Overall, your code looks good.

If you're going to put the API on another server, thus another domain, take a look at CORS which will be needed to enable js to fetch a different domain.

Upvotes: 2

Related Questions