I have an API powered by Django rest framework and I also use the default pagination option:
{
"count": 40,
"next": "http://127.0.0.1:8000/api/task/?page=2",
"previous": null,
"results": [{},{}...]
}
On angular side, I'm using ngResource to consume my api wiht the following code:
var task_resource = $resource('/api/task/:taskId/', {taskId:'#id'},{
query : {
method : 'GET',
isArray : false
}
});
I just want to be able, when the user click a 'next' button or scroll down to the bottom of the page to query the 'next' page until the end. I know I only have to GET on "next" field but if I do that, I will not use the $resource I defined.
I am wondering what is the solution for such a common pattern with angular and an API.
Since the 'next' url is absolute, you could simply use angular's built-in $http service for those requests. Something like $http.get(data.next).success(function(data){});
Another way would be to create your own custom pagination serializer as described here: http://www.django-rest-framework.org/api-guide/pagination#custom-pagination-serializers
Then you would need to create your own version of the NextPageField, and make it output without the domain part.
The standard implementation for the NextPageField can be found here:
https://github.com/tomchristie/django-rest-framework/blob/560f428e24c7676c660114c2daa6017ff61074ad/rest_framework/pagination.py
Related
I want to implement pagination in my "angularJs" application. I have a dropdown menu that I'm using angular-ui for that. I want at first application loads the first set of data from "API" and when scrolled to button with the help of ngInfiniteScroll requests the next set of data from the "API". For example at first in request "URL" I add "page=1" as parameter and for any request I add to that "page" number.
My question is that for this pagination should the "API" has the pagination capability or I can do this for any "API"?
If the "API" need to have that capability, do you know any "API" with pagination capability so I can test my application?
Appreciate any help.
my code is here
The API has to support pagination in the sense that it should be able to respond to queries with fragments of data, instead of dumping all the data in one go.
For example:
For page 1:
your.api.endpoint/your/resource/path/countries?offset=0&pageSize=50
For page 4:
your.api.endpoint/your/resource/path/countries?offset=200&pageSize=50
You can build your URL params for pagination however you want though, e.g. /countries?pageNo=4&pageSize=50, /countries?from=200&to=250 etc.
Note:
When you implement server-side pagination, you need to implement server-side sorting and filtering too; that's because with server-side pagination the client can only see 1 page of data and therefore sorting or filtering would be inaccurate.
EDIT to show example of mocking API response
In your service you might have something like this:
return $http({
method: 'GET',
url: 'your.api.endpoint/your/resource/path/countries?offset=200&pageSize=50'
})
And you'd replace it with:
var pageOfData = { ... }; // Mocked data here.
return $q(function (resolve, reject) {
resolve(pageOfData);
});
I'm building an API with Symfony 3 following the JSON API specification (Documentation).
When submitting new data, the request has this format :
{
"type": "entity",
"id" : null,
"attributes" : {
"name" : "Test name"
}
}
But the problem is the request does not fit the format expected by symfony's Forms because of the extra object attributes.
So I want to be able to transform the request before the form submit in order to make the form able to populate the underlying Entity.
I have tried to register an FormEvents:PRE_SUBMIT and do the logic in it but it seems I have no access to the Request content.
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$data = $event->getData();
var_dump($data);
die();
});
The $event->getData() is null.
I have also see there is possibility to register DataTransformer but it is registered per field, and has no access to the Request too.
I don't want to do it manually in the Controller as this will occur on all my forms (or at least the majority), so I search for a more generic way to transform the request, but at this point I can't figure out how to do this.
Thanks for help.
Your EventListener does not have access to your Request, nor does your Form itself.
The best and cleanest way to do this in my opinion would be to define a custom RequestHandler for your Forms, extending the NativeRequestHandler that parses your Request by default.
Then you only need to execute $builder->setRequestHandler() to apply this to your Forms.
So I'm trying to AJAX a single solr doc from my results list to a "doc view" view. I'm trying to use AngularJS to AJAX to my view render method and display the doc that way, but I can't seem to get the angular to work and I'm not sure I'm doing things correctly on the Play side either. Would you at least be willing to tell me if what I'm trying to do will work? The Angular error comes from the docText.text(); call. Here is my code:
Angular controller code:
var docText = $resource("http://localhost:9000/views/full-doc-text.html", {
text: {method: 'PUT'}
});
$scope.handleViewText = function(value) {
docText.text({doc: value});
}
Java code:
public static Result viewText() {
JsonNode json = request().body().asJson();
//do stuff here
return ok(viewtext.render(json));
}
route:
GET /views/full-doc-text.html controllers.Application.viewText()
I see three problems with the code above;
1.The definition of docText resource is not correct. if your read the angularjs manual here you'll see that $resource has 4 parameters. First one is resource url, second is parameter defaults, third one is custom actions and forth one is resource options where last three of them are optional. In your code you pass custom actions as the second parameter, which should be the third. And since you don't have any parameters in your resource url second parameter must be null. So first correction is:
var docText = $resource("http://localhost:9000/views/full-doc-text.html", null, {
text: {method: 'PUT'}
});
2.You define your text action's HTTP method as PUT however in your routes file you are handling GET requests for your desired action. You should change your route definition as:
PUT /views/full-doc-text.html controllers.Application.viewText()
3.PUT method is usually used for update operations when implementing a RESTFULL service. In your case you don't seem to be updating anything. So I suggest to use POST method just for convention.
I'm using AngularJS to integrate with a REST service which has already been built.
The REST API uses the following form for queries:
http://the.site/person/search/smith%20male (this searches for people called smith who are male)
I'm aware that this form isn't the best and will be ultimately getting the API changed to use a URL parameter.
Currently I'm just defining a resource inside my controller:
$scope.Summary = $resource("http://the.site/person/search");
this.Summary.query({ terms : 'smith male' });
but that generates URL's of the form /person/Search?terms=smith%20male
Is there a way to modify or override the URL used? I'm more familiar with Backbone where I was able to provide a url() function in my which generated the correct form of URL.
$scope.Summary = $resource("http://the.site/person/search/:terms");
this.Summary.query({ terms : 'smith male' });
I'm trying to post an array using a POST request to a specific page, the target page generates a csv and send me back the stream, right now i'm doing using ExtJs Ajax class, but that won't work as i need to make a normal HTTP request not ajax, my current code is as follows:
Ext.extend(Players.panel.Home,MODx.Panel,{
exportSubscribers: function(btn,e) {
MODx.Ajax.request({
url: Players.config.connectorUrl
,params: {
action: 'mgr/player/getSubscribers'
}
});
}
});
The exportSubscribers function is executed from a normal ExtJs button
{ xtype: 'button'
,text: 'Export Subscribers'
,preventRender: true
,handler: this.exportSubscribers
}
What class should i use to turn this into a normal request?
Thanks.
There isn't a class to do a normal request. I known two ways to accomplish a file download:
Use a hidden form in the page, replace the field values and invoke the form's .sumbit method from ExtJS button handler to do the POST request you want.
Replace your button by an HTTP anchor if you can use a GET request to make the server return the file: Download CSV'
You'd be better off making a local request to your server, and then in your server-side code make a cURL request to the CSV source. That way, you can make a non XMLHttpRequest method to get your data.