Question

Below is the function I have used to fetch more photos from a service provider once clicked on more button:

showMore: function(){
        this.$.resultList.collection.fetch({strategy:"merge",rpp:50});
    }

This will call the fetch method defined in collection,

fetch: function(opts) {
        this.params = {
            feature: this.methodType || "popular",
            image_size: 3,
            sort: "created_at",
            rpp: opts && opts.rpp || 25
        };
        return this.inherited(arguments);
    },

This is working fine, but the problem is once more button is clicked, it should fetch another set of 25 photos and append it to my collection, but what actually happening is sometimes, it shows only say 5 photos along with previous photos .

What I understand by "merge" strategy is, if the records received is same as previous records, it will take only those records which are different from previously fetched records and updates the primarykey of the duplicate records.So one reason i am able to figure out is that, may be, it is fetching 25 photos next time, but because most of them are same as before, it is showing only those which are different from the previous fetched photos.

If i go with the "add" strategy, it works fine for one time, i.e, it shows another set of 25 photos appended to the collection, most of them are again same. But if click on more button one more time, no records are being added to the collection.No idea why this is happening.

How should i approach, if i want to fetch only new photos and append it to the collection.

Was it helpful?

Solution

Using the merge strategy is the right approach. Your description of merge is mostly accurate except that it doesn't update the primary key but instead updates the data for existing records with the same primary key.

It's difficult to say why using "add" doesn't always work. If the records don't have a primary key (which is id by default), "add" and "merge" should always add the records to the collection (unless you're using mergeKeys). If they do have a primary key, it's possible that you're trying to add duplicate records which Enyo will complain about and abort. Check your console log.

Without code, the only other suggestion is to set breakpoints and step through enyo.Collection.merge.

Here's an example of fetching records into a collection. If you comment out setting the id, merge and add strategies will always add records. If you comment out the merge strategy, the code will eventually error when requesting more records.

enyo.kind({
    name: "ex.MockSource",
    kind: "enyo.Source",

    fetch: function(rec, opts) {
        if(rec instanceof enyo.Model) {
            rec.setObject(Faker.Helpers.createCard());
        } else if (rec instanceof enyo.Collection) {
            var count = opts && opts.count || 25;
            var cards = [];
            for(var i=0;i<count;i++) {
                var card = Faker.Helpers.createCard();

                // artificial id to force merges
                card.id = enyo.now()%40;
                cards.push(card);
            }

            opts.success(cards);
        }
    }
});

enyo.store.addSources({
    mock: "ex.MockSource"
});

enyo.kind({
    name: "ex.App",
    kind: "Scroller",
    bindings: [
        {from: ".data", to: ".$.list.collection"},
        {from: ".data.length", to: ".$.count.content", transform: function(v) {
            return enyo.format("Displaying %s records", v);
        }}
    ],
    components: [
        {name: "count"},
        {name: "list", kind: "DataRepeater", components: [
            {kind: "onyx.Item", components: [
                {name: "name"},
                {name: "phone"}
            ], bindings: [
                {from: ".model.name", to: ".$.name.content"},
                {from: ".model.phone", to: ".$.phone.content"}
            ]}
        ]},
        {kind: "onyx.Button", content: "More", ontap: "moreTapped"}
    ],
    create: enyo.inherit(function(sup) {
        return function() {
            sup.apply(this, arguments);
            this.set("data", new enyo.Collection({
                defaultSource: "mock"
            }));

            this.fetchRecords();
        };
    }),

    fetchRecords: function() {
        this.data.fetch({
            count: 5,
            strategy: "merge"
        });
    },

    moreTapped: function() {
        this.fetchRecords();
    }
});

new ex.App().renderInto(document.body);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top