-1

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.

ramblinjan
  • 6,578
  • 3
  • 30
  • 38
  • You'd better simplify your question, otherwise none will answer you. http://stackoverflow.com/questions/how-to-ask – waldyr.ar Dec 23 '13 at 20:04

1 Answers1

1

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.

air_hadoken
  • 611
  • 4
  • 5
  • I am new to this can you explain a detailed way?? – user3083664 Dec 24 '13 at 17:18
  • I updated the answer with more detail. Does that help? – air_hadoken Dec 24 '13 at 23:03
  • It worked thanks a lot. also can I dynamically change the max_fav=3&max_reco=3 field. Also can I have multiple findAll in the one model. – user3083664 Dec 26 '13 at 18:32
  • The main thing is I wanna change the section after api.php i.e "stores-for-you?max_fav=3&max_reco=3" dynamically also the page id and section id is there some way to do so. – user3083664 Dec 26 '13 at 18:35
  • Yes, but don't use the string format for your findAll spec if you want to use the 3s as defaults and then override them. instead, use an object: `findAll : { url : "/api.php/stores-for-you", type : "get", data : { max_fav : 3, max_reco : 3 }}` – air_hadoken Dec 26 '13 at 23:38
  • Dotwoff = can.Model.extend("dotwoff",{ findAll: { url: '/api.php/specialoffers?', type: 'GET', data: { max : 1 , pid : 977 , sid : 9081 } } }, {}); this is what I have done and is working fine. So now I can just Defer/Override the values later for different set of values right using the same "data:" ??? – user3083664 Dec 30 '13 at 14:33
  • Dotwoff.findAll({ sid : 9082 }) will resolve to the next section, for example, so yes, I think you've got it – air_hadoken Dec 30 '13 at 21:47
  • how should i write the control for the same i am a bit confused – user3083664 Dec 31 '13 at 15:07
  • I am calling the control function using Featoff.findAll({}, function(offerResponse) { new Feat('.mn_featStr', { offerdata: offerResponse }); }); and the main function is defined in the control.js Feat = can.Control({ init: function() { this.element.html(can.view('images/js/mn/temps/featured.ejs', { offerdata: this.options.offerdata, secTitle: this.element.attr('data-title') })); } }); is there a way to combine those two – user3083664 Dec 31 '13 at 15:29
  • Your init() function can do this instead: ```var that = this; can.view("images/js/mn/temps/featured.ejs", Featoff.findAll({})).done(function(frag) { that.element.html(frag); })``` If you pass a can.Deferred as your data for can.view, you get back a can.Deferred that resolves to the view rendered with the data. If you don't know how to use Deferred or Promises, go learn them right now as they'll save you a ton of headaches. – air_hadoken Dec 31 '13 at 23:34
  • what does frag stand here for? parameters – user3083664 Jan 02 '14 at 15:31
  • Feat = can.Control({ init: function() { var that = this; can.view('images/js/mn/temps/featured.ejs', featoff.findAll({})).done(function(frag) { that.element.html(frag); offerdata: that.options.offerdata, secTitle: that.element.attr('data-title') }); })); }); does this look good ??? – user3083664 Jan 02 '14 at 17:15
  • the parameter to the callback function is called ```frag``` because it is a document fragment. It looks like you need to send more properties to your view template; I missed that the first time. so the findAll bit would look like this: ```...red.ejs', Featoff.findAll({}).then(function(d) { return { offerdata : d, secTitle : that.element.data('title') }; })).done(function(fr...``` – air_hadoken Jan 03 '14 at 02:42
  • i am confused whether to pass offerdata : d or should i pass it with that.options.elements?? – user3083664 Jan 03 '14 at 15:25
  • Hi tried all the combinations with the Feat = can.Control({ init: function() { var that = this; can.view('images/js/mn/temps/featured.ejs', Featoff.findAll({}).then(function(d) { return { offerdata : d, secTitle : that.element.data('title') }; })).done(function(frag)) { that.element.html(frag); } } }); but still it is showing me some syntax error with the return line – user3083664 Jan 03 '14 at 18:37
  • you have one too many right parens after ```frag``` and you're missing one after the ```done``` callback. – air_hadoken Jan 07 '14 at 01:04
  • Feat = can.Control({ init: function() { var that = this; can.view('images/js/mn/temps/featured.ejs', featoff.findAll({}).then(function(d) { return { offerdata : d, secTitle : that.element.data('title') }; })).done(function(frag) { that.element.html(frag); }) }}); this is working now. Just wanted to know what method should i use to reuse the above template with different set of data parameters in findALL ??? and how to do that ?? – user3083664 Jan 07 '14 at 18:43
  • And also i have this question why do we need to create different control for each section ? can we have a single base controller and just reuse it with overriding the template view and the parameters. – user3083664 Jan 07 '14 at 18:54
  • Also can i have multiple views inside a single control with many templates. ?? – user3083664 Jan 07 '14 at 18:56
  • Too many questions for this comment thread. Ask new SO questions. – air_hadoken Jan 07 '14 at 23:01
  • Feat = can.Control({ init: function() { var that = this; can.view('images/js/mn/temps/featured.ejs', featoff.findAll({}).then(function(d) { return { offerdata : d, secTitle : that.element.data('title') }; })).done(function(frag) { that.element.html(frag); }) }}); this is working now. So now I wanna reuse the same Feat control with different set of parameters in the findAll, How can i do so? What method to use and how to use?? also can I also defer or override the can.view for the same ?? – user3083664 Jan 08 '14 at 01:52
  • Too many questions for this comment thread. Go up to the top of the page and press "Ask Question". – air_hadoken Jan 08 '14 at 04:30
  • so i declare the control like var a = can.Control.extend({}). So the var is private within the function scope. what is the advantage of using var over like declaring an empty object var b={} and then defining the control like b.a = can.Control.extend() – user3083664 Jan 15 '14 at 20:49