Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dgrid with async stores ?!? #109

Closed
ghost opened this issue Mar 2, 2012 · 6 comments
Closed

dgrid with async stores ?!? #109

ghost opened this issue Mar 2, 2012 · 6 comments

Comments

@ghost
Copy link

ghost commented Mar 2, 2012

Relevant code in original dojo/store/JsonRest.js looks like this:

    var results = xhr("GET", {
        url: this.target + (query || ""),
        handleAs: "json",
        headers: headers
    });
    results.total = results.then(function(){
        var range = results.ioArgs.xhr.getResponseHeader("Content-Range");
        return range && (range=range.match(/\/(.*)/)) && +range[1];
    });
    return QueryResults(results);

I tried all sorts of variations of this:

    var results = xhr("GET", {
        url: this.target + (query || ""),
        handleAs: "json",
        headers: headers
    });

    results = results.then(function(response){
        var r = response.rows;
        r.total = response.total_rows;
        return r;
    });
    return QueryResults(results);

In the origial, results are returned as is and in my case it is results.rows that need to be returned.

Now, as soon as I do that, results.total either does not end up being returned as "promised" or as I suspect dgrid is not using the promised value and is instead using either the results.length or worse the default value of 25.

While I am personally new to JS and much of web dev, half a dozen folks on #dojo have tried to help. Out of numerous tests that exist and as I was told work ;) I am still not able to identify any that work with async (xhr like) store.

I need to get this to work in original JsonRest.js + above changes - to see paging work with async stores. Then I need to replace xhr with io.script , for a stripped down JSONP version. But in all those cases results.child.array needs to be returned to dgrid, as well as an indication of how many records are available to the query, so that dgrid will know to call store.query for more data (I hope).

@ghost
Copy link
Author

ghost commented Mar 2, 2012

working non-working demo is available here
http://grahovo.iriscouch.com/ws/3/JsonRest.html
lines 165 to 176 in custom/JsonRest.js

17 rows in viewport
25 rows returned
79 rows available and should be reported by results.total

slidebar should be about 1/5 of viewport height (17 / 79)
it should not be more than half or 17 / 25

thanks

@kfranqueiro
Copy link
Contributor

As I told you earlier on IRC, you need to be setting total on the immediate return of the results object. Setting it within the promise means it's not set immediately, which also means QueryResults is probably defaulting it to the length of the returned result set (which is only the length of the page - 25).

Here's an expansion of what I was trying to tell you on IRC earlier:

var dfd = xhr("GET", {
    url: this.target + (query || ""),
    handleAs: "json",
    headers: headers
});
var results = dfd.then(function(response){
    // dig out the inner property containing the array of items
    return response.rows;
});

// Assign a promise to the total property on the results object being returned;
// this promise will be resolved around the same time as the previous one
results.total = dfd.then(function(response){
    return response.total_rows;
});

// Now wrap the results object; since it already has total defined,
// QueryResults should leave it alone, and consumers should pick it up properly.
return QueryResults(results);

@ghost
Copy link
Author

ghost commented Mar 2, 2012

I have uploaded dojo source to help wih trying to debug minified cdn code.
it's here http://grahovo.iriscouch.com/ws/4/JsonRest.html

@neonstalwart
Copy link
Contributor

@kfranqueiro the promise returned from xhr is frozen and so results.total cannot be assigned to it. i believe this is also a bug in JsonRest store. (cc: @kriszyp) assigning to results.total is futile in browsers that support Object.freeze.

the right way to do this for @teslan is along these lines

var dfd = new Deferred();

var results =  = xhr("GET", {
    url: this.target + (query || ""),
    handleAs: "json",
    headers: headers
});

Deferred.when(results, function (response) {
    return response.rows;
}, dfd.reject);

dfd.total = Deferred.when(results, function (response) {
    return response.total_rows;
});

return QueryResults(dfd);

or use delegate as is done in QueryResults. someone want to open a bug in dojo?

@neonstalwart
Copy link
Contributor

the delegate version looks something like this:

    var dfd = xhr("GET", {
        url: this.target + (query || ""),
        handleAs: "json",
        headers: headers
    });

    // wrap the frozen promise so we can assign properties to the wrapper
    var results = lang.delegate(dfd.then(function (response){
        return response.rows;
    }));

    results.total = dfd.then(function(response){
        return response.total_rows;
    });

    return QueryResults(results);

@neonstalwart
Copy link
Contributor

opened dojo bug for JsonRest - http://bugs.dojotoolkit.org/ticket/14930

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants