uberVU / mozaic

JS Framework for building SPA
http://ubervu.github.com/mozaic/
26 stars 17 forks source link

Invalidate on fetch is not followed by any event in case of duplicates #66

Closed valentinzberea closed 11 years ago

valentinzberea commented 11 years ago

We are triggering an invalidate each time before fetch.

https://github.com/uberVU/mozaic/blob/master/core/datasource/channel/read.coffee#L126-L131

            receiving_channel.url = Utils.render_url(conf.url, params, [], conf.fetch_through_POST)
            # Trigger a custom invalidate event before fetching the
            # collection from the server (invalidate gets triggered
            # every time a request is made to the server). The format
            # of the event is: model, collection
            receiving_channel.trigger('invalidate', null, receiving_channel)
            receiving_channel.fetch(fetch_params)

And this is good because we can tell when a widget enter the loading state:

            previousStates = _.clone(@loadingStates)
            for event, i in params
                if event.type == 'no_data'
                    @loadingStates[i] = 'empty'
                if event.type == 'invalidate'
                    @loadingStates[i] = 'loading'
                if event.type in ['sync', 'change', 'reset', 'add', 'destroy']
                    # Check to see if the data on this specific channel is empty
                    if @isChannelDataEmpty(event, @loading_channels[i])
                        @loadingStates[i] = 'empty'
                    else
                        # Data has arrived on loading channels, the state should
                        # be available
                        @loadingStates[i] = 'available'
            @transitionState(@loadingStates, previousStates, params)

But what happens when you try to add new items to a channel (paging scenario)? Before the fetch an invalidate is triggered followed by several add events (each one for the new items added to collection).

But when you receive only duplicates the add event is not triggered anymore and the state remains in loading indefinitely.

aismail commented 11 years ago

Ouch :(

There should be no duplicates in the API. Why do we have such a thing?

valentinzberea commented 11 years ago

Let's say you are paginating through the results from Facebook API. You cannot control the results.

A workaround would be to define a postFetch hook and in there trigger a no_data event if nothing changed:

postFetch: (response) ->
     if @previous_length? and @previous_length is @length
         @trigger_no_data()
     else
         super(response)

     @previous_length = @length