Canjs findall and findone? - canjs

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.

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.

Related

Symfony2, doctrine2, session, best way to paginate search page

Let's imagine we have simple data and want to make pagination of it. It's not hard to do, simple _GET var with page number others doctrine with offset will allow us to do it in easy way, BUT How should it look like in search page? Let me explain.
For example we have simple route with /search url. Where we have form for our search. When use input string we user POST method on same page and will get result. Simple enough but if we add pagination here it become a problem with storing "inputed string".
If we store in session on search query it will be solution BUT... it's not. Why? User input search string - get result with pagination (here search string already in session) after that leave the page (or close browser, or left to another page). When he will return data from session will show him 'result of old query'...
So question is, what is the best practice for such situation? I want simple search query + pagination of it but if user left page - clear result.
Using POST instead of GET for search query is kinda unusual and not really safe. Since search query operations are read-only you should use GET to access/get the data. POST is used for updating or creating resources.
And how you will go back/forward in the pagination (using browser's buttons)? You always will be getting an alert box. AND you cannot share/bookmark the search query url.
BTW to answer your question, sessions and hidden input fields would be the way to go. You also can use a combination of get and post
When should I use GET or POST method? What's the difference between them?

Symfony2 and filter, right strategy

I'm asking what is the best strategy for filtering with Symfony2.
I want to filter a table of entities (hotels). This filter should allow me to :
choose hotels with or whitout email, with or without web site etc.
choose hotels based on state and/or city (relation OneToMany)
choose what information I want to display on the table with checkboxs (for example display "email adress" on the hotel table, but do not display "tel" or "web site").
First I think to build the filter form on the HotelController. When the filter is submitted, I had a FlashBag for every $_POST sended, redirect to the same page, and if there are FlashBag I send cookies to the $reponse. Then I display the table filtered with data who are on the cookie.
But I dont't really like this, cause I had a very big indexAction() on the HotelController, and I think it'as not really clean to change $_POST to FlasBag to Cookie, is it ? I do this redirection, cause by refreshing the page, data are not posted again.
I'm also asking a question, to prevent a too big IndexAction() method, can I put some code to another method, for exemple a method PostToFlashBag() and another FlashBagToCookie(), or every method on a Controller has to end with the word "Action" and must be accessible with the router ?
Then, I think to another thing : had an entity "Filter", with every row I need. For exemple "WithEmail", "DisplayTel" etc.. Then I can build a FilterType easily, and update the Filter entitie, to redirect to the same page (again, to prevent reposting data if the user refreshes the page). Finally, I can display the table with the object Filter, with a method on the HotelRepository.
That seems great, but I'm a little worry because the filter entity will only have one entry, and I have to find the Filter(1). Due to MVC, is it correct to have a model with only one entry ?
What strategy would you choose (maybe another one) ? I'm interesting to learn good practice with MVC and Symfony2 devloppemnt.
Having a dedicated model class - let's call it Filter - that will receive the values input by the user, is definitely the way to go.
More over, use the Symfony2 form on this input, so you can have validation, and be sure that the withEmailis trully a boolean, etc. From you Filter, build you SQL/Doctrine query and return what your controller have to return, be it a view, or raw datas.
You can have any method you want in a controller. After all, controllers in Symfony2 are plain old PHP objects. They only have to implement ContainerAwareInterface. Usually they inherits Controller, but this inheritance only brings some proxy methods, like getDoctrine or render.
The only convention is that methods which are used as route must end with Action

Pagination of search results

I have a form where user is able to choose search options. When user clicks "Search" button,
an appropriate GET controller's action is invoked:
public ActionResult Search(SearcherViewModel model, int pageNo=1)
{
var results = xService.GetSearchResults(model);
return View("Index", results);
}
GetSearchResults method does not connect to the database, but instead it call some third party web service. This however is not the main issue.
Therefore, the url can look as follows:
http://localhost/Search?startDate=20120210&offerType=3&foodId=4&&Destination=456
How can I implement a pagination of search results? In particular, how should I construct the page numbers and how to use my model?
Kinda depends on how much stuff you are paginating. If it is small then you can hold the whole thing in javascript memory using preloading and then paginate based on the javascript objects. If you are looking at potentially tens of thousands or more of items to paginate, then you may consider preloading part of that and then using ajax to load pages later on depending on how the user navigates.

OpenRasta - Providing Filter, Sorting and Paging for List Resources

We are creating a REST API using OpenRasta and apart from regular GET, POST, PUT and DELETE on all resources, we are also providing GET on resources with plural names. So a consumer of the API can GET, POST, PUT and DELETE on User and also perform GET on Users which will return List<Users>. Now we want the clients to be able to filter and sort it by it's properties and allow to support paging for showing data in paged tabular formats.
Although, I looked at WCF Data Services Toolkit home page and looks like it can be useful but after looking at blog posts and Getting Started page, I couldn't understand how I can use it to solve my problem in OpenRasta.
Or is there anything else simpler that I can do?
OR doesn't support stuff like OData for that functionality, mainly because it leads to very unrestful systems.
If /users is "the list of users", then it is a different resource than /users/1 (the first page of users) or /users/byName/1 (the first page of users ordered by name).
You can of course implement all this easily by registering a URI that has query parameters, as those are optional
.AtUri("/users?page={page}&filter={filter}
And your handler can look like
public List<User> Get(int page = 0, string filter = null) { ... }

Hiding Query String Parameters

I have a GET action for creating records. Because the page is somewhat dynamic, I don't use a model to hold the data. I go off to do some OAuth, only to return to the create screen later on. In order to pass the data back, I am redirecting with a query string. I parse the query string in the GET action, and then show the view. The thing is, the query string is showing up in the browser. This displays pseudo-sensitive data.
Since I am only using the query string for transferring data, I am wondering if I can throw the query string away to prevent it from showing up on the browser.
Otherwise, is there a way to go to another action without redirecting? I've found, if I call the "other" action method directly, it tries to find the view of the original action. I can explicitly change the return View(viewModel) line to return View("create", viewModel) but that seems really dirty.
You should consider changing the action to accept POST requests. At least this will prevent the sensitive information from appearing in the browser. For extra security, your site should be served via SSL.
The other thing you can try is encrypting the sensitive values or the entire query string. The only problem is that this, too, will be preserved in the browser's history unless you require users to log in.
It looks like your action method is trying to do too much. Authentication/authorization is a separate concern which should not be part of the action method. It is better to move the authentication work in to an action filter.
Create an class that extends authorization attribute and override its OnAuthorization method to do your authorization work.
This frees your controller action method to accept POST requests.

Resources