Search code examples
backbone.jscollectionsbackbone.js-collections

Why is my backbone.js collection not loading the correct list of data?


Here is my model and collection definition:

let PhotoModel = Backbone.Model.extend({
    urlRoot: '/api/Photo',
    defaults: {
        id: "2",
        import_id: "1",
        original_filename: "",
        filename: "IMG_8199 - Version 2.jpg",
        aws_url: "https://s3.amazonaws.com/nakamoto.ca",
        aws_bucket: "nakamoto.ca",
        aws_s3_source_path: "source/2016/02/IMG_8199_-_Version_2.jpg",
        aws_s3_compressed_path: "compressed/2016/02/IMG_8199_-_Version_2.jpg_1600x1200",
        aws_s3_thumb_path: "thumb/2016/02/IMG_8199_-_Version_2.jpg_400x400",
        capture_date: "2016-02-27 18:45:02",
        upload_date: "2017-04-18 21:26:59",
        file_size: "2026722",
        width: "3264",
        length: "2448",
        camera_make: "Apple",
        camera_model: "iPhone 6 Plus",
        software: "Aperture 3.6",
        latitude: "45.225206",
        lat_ref: "N",
        longitude: "45.292572",
        lon_ref: "W",
        altitude: "0.000000",
        apple_note: "iPhone 6 Plus back camera 4.15mm f/2.2",
        iptc_headline: "",
        iptc_caption: "",
        iptc_credit: "",
        iptc_rating: "0",
        iptc_city: "",
        iptc_province_state: "",
        iptc_country: "",
        iptc_tags: "",
        favorite: "0",
        checksum: "4749e94d3eec7b6bf6a0136d8dc3457c",
        public_flag: "0",
        raw_exif: ""
    },

    parse: function(response_data) {
        return response_data.data;
    }
});

let PhotoCollection = Backbone.Collection.extend({
    url: '/api/Photo',
    model: PhotoModel,

    parse: function(response_data) {
        return response_data.data;
    }
});

and here is the output from calling /api/Photo (copy and pasted from Chrome inspector):

{model: null, id: null, request: "GET", status: 1,…}
model: null
id: null
request: "GET"
status: 1
message: "grabbed some records with: SELECT * FROM `photo` WHERE 1 LIMIT 1, 10"
count: 10
page: 1
per_page: 10
data: [{id: "2", import_id: "1", original_filename: "", filename: "IMG_8199 - Version 2.jpg",…},…]
0: {id: "2", import_id: "1", original_filename: "", filename: "IMG_8199 - Version 2.jpg",…}
1: {id: "3", import_id: "1", original_filename: "", filename: "IMG_8192 - Version 2.jpg",…}
2: {id: "4", import_id: "1", original_filename: "", filename: "IMG_7961 - Version 2.jpg",…}
3: {id: "5", import_id: "1", original_filename: "", filename: "IMG_8086 - Version 2.jpg",…}
4: {id: "6", import_id: "1", original_filename: "", filename: "IMG_7947 - Version 2.jpg",…}
5: {id: "7", import_id: "1", original_filename: "", filename: "IMG_8113 - Version 2.jpg",…}
6: {id: "8", import_id: "1", original_filename: "", filename: "IMG_8009 - Version 2.jpg",…}
7: {id: "9", import_id: "1", original_filename: "", filename: "IMG_8109 - Version 2.jpg",…}
8: {id: "10", import_id: "1", original_filename: "", filename: "IMG_7967 - Version 2.jpg",…}
9: {id: "11", import_id: "1", original_filename: "", filename: "IMG_8004.jpg",…}

and here is my test code:

    $(function() {
        var photo_album = new PhotoCollection();
        photo_album.fetch({
            success: function (photo_album, response) {
                photo_album.each(function(photo, index, all) {
                    console.log(photo.get('filename'));
                });
            }
        );}
    };

When I look in the console I see the same filename repeated 10 times, and it is the default filename from my Photo model (IMG_8199 - Version 2.jpg). I expect to see 10 different filenames as per the data returned by /api/Photo (above).

Can anyone tell me where I am going wrong? I feel like this must be something really obvious - this is my first attempt at backbone.js.

If I log the response_data.data in the Parse method of the collection, I see the correct data array from the json data.

Incidentally, I am able to successfully load individual Photo models without any problems.

Any help would be greatly appreciated, thanks!


Solution

  • From change log of 0.9.9

    After fetching a model or a collection, all defined parse functions will now be run. So fetching a collection and getting back new models could cause both the collection to parse the list, and then each model to be parsed in turn, if you have both functions defined.

    Chances are your individual model fetch succeeds because of proper response structure from the server, but the collection fetch response passed to model's parse is simply an object like this:

    {id: "3", import_id: "1", original_filename: "", filename: "IMG_8192 - Version 2.jpg",…}

    which doesn't have a data property, so

    parse: function(response_data) {
        return response_data.data;
    }
    

    in the model will return undefined, leaving default values in the newly created model. You have to update the model parse to take care of both cases