canjscanjs-model

Canjs findall and findone?


So right now I am accessing the data using the findAll: 'GET api.php/stores-for-you?pid=977&sid=5938&max_fav=3&max_reco=3' which is a way to access the api for my application where pid is the page id and sid is the section id. So each page has different pid and sid. So as of now I have to make findall call for each api call which i find not a good option.

I was thinking if i can use findone along wih the Findall here. where I can access the api to the particular stores-for-you and then use findone to hit the particular url with the parameters.

Can anyone help me out. If the question is still not clear can you just write me back i would try to explain it more.


Solution

  • Your findAll shouldn't have the page and section IDs hardcoded into the GET string, since that would make your can.Model specific to just that page. Your code that calls findAll should be providing those.

    can.Model subclasses represent a type of data that you get from the server. findAll is meant to retrieve some number of objects of that type. Your GET string seems to want to return stores. We could call your model WebStore (I'm avoiding using "Store" because that word has a different meaning in CanJS).

    can.Model.extend("WebStore", {
      findAll : "GET /api.php/stores-for-you?max_fav=3&max_reco=3"
    }, {});
    

    In this spec for your findAll, we've left in some paging keys (max_fav and max_reco seem to be result limiters), so that other code can't come along and request 3000 results at a time. The other ones, though, are for specific pages. They're effectively queries. If you put them into your findAll spec, your Model could only ever retrieve that page, limiting its reusability.

    so now in other code, probably a controller prototype init():

    var ws_ajax = WebStore.findAll({ pid : 977, sid : 5938 });
    ws_ajax.done(function(stores) {
      //Handle the array of 0-3 stores returned from the server. 
    });
    

    So now you can call on other pages and sections later on in other code just by doing the same call with different pid and sid values. You don't need to try to hack findOne for a different page.

    HOWEVER... if for some reason you use that particular page/section combination frequently, you might consider using another function on your WebStore model's static properties, and then it would look like this:

    can.Model.extend("WebStore", {
      findAll : "GET /api.php/stores-for-you?max_fav=3&max_reco=3",
    
      findMyPage : function() {
        return this.findAll({ pid : 977, sid : 5938 });
      }
    }, {});
    

    Note that findMyPage has no special meaning in CanJS. You're just wrapping findAll with frequently used values to save yourself excessive typing and maintenance headaches if those values change.

    An exercise left to the reader is to implement "findMyOtherPage" which would find... your other page.

    EDIT: more detail added on request.