0

I have a API that sends out a paginated result of data and I want it to be consumed my Ext JS app but I don't know how to supply the needed parameters.

Here is the response I expect:

{
  "currentPage": 1,
  "from": 1,
  "items": [
    {
      "id": 1,
      "customer": "Customer 1",
      "movie": "Movie 1",
      "dateRented": "2021-01-25T01:22:42.143",
      "dateReturned": "2021-01-25T01:22:50.447"
    },
    {
      "id": 2,
      "customer": "Customer 2",
      "movie": "Movie 2",
      "dateRented": "2021-01-25T01:22:42.15",
      "dateReturned": "2021-01-25T01:22:54.573"
    }
  ],
  "pageSize": 2,
  "to": 2,
  "totalCount": 1000003,
  "totalPages": 500002,
  "hasPreviousPage": false,
  "hasNextPage": true
}

Here is the endpoint:

/api/Rentals/{currentPage}/{pageSize}

Here is my Ext store but I don't know how I will be able to pass the value for currentPage and pageSize:

Ext.define('Vidly.store.PagedRentals', {
    extend: 'Ext.data.Store',
    alias: 'store.pagedrentals',
    storeId: 'pagedrentals',
    model: 'Vidly.model.PagedRental',
    autoLoad: true,
    autoSync: true,
    proxy: {
        type: 'rest',
        url: 'https://localhost:44313/api/Rentals/',
        useDefaultXhrHeader: false,
        reader: {
            type: 'json',
            headers: { 'Accept': 'application/json' },
        },
        writer: {
            type: 'json',
            writeAllFields: true
        }
    },
});

And here is the model:

Ext.define('Vidly.model.PagedRental', {
    extend: 'Ext.data.Model',
    fields: [
        { name: 'currentPage', type: 'int' },
        { name: 'from', type: 'int' },
        { name: 'to', type: 'int' }, 
        { name: 'pageSize', type: 'int' },
        { name: 'totalCount', type: 'int' },
        { name: 'totalPages', type: 'int' },
        ],
    hasMany: 'Rental',
});

I hope someone can help me with my problem. Thank you.

7
  • Take a look at the beforeLoad method and change the url accordingly. Commented Feb 4, 2021 at 12:17
  • Where do I put the beforeload method? And it is it possible to update the parameters on the fly? Ex: next page, previous page or changing pageSize? Commented Feb 4, 2021 at 14:18
  • It is possible to do with buildUrl method. Your model is a little bit strange, it must contain the id, customer, dateRented, returnDate fields.. and your store must have rootProperty: 'items'.. Have you checked your code? Commented Feb 4, 2021 at 14:52
  • You could add a listener on the store -> listeners -> beforeload. Inside the the callback you can do something like (store is the first param of that fn) -> store.getProxy().getExtraParams() -> modify -> set and load. But as Arthur and Zoltan mentioned, i would suggest to improve the backend response structure (model) (if possible) as well as use query instead of pathparameters. This will make your life much easier. Commented Feb 4, 2021 at 17:10
  • Actually I am trying to learn ExtJS for multiple scenarios. Yes changing the API would fix my problem but what if I encountered a scenario that I don't have control over the API. These are the things that I am preparing to. Commented Feb 5, 2021 at 3:18

1 Answer 1

1

Ext's rest proxy is designed to use standard REST APIs where paging and filtering options are passed in as query parameters. I.e. something like

https://localhost:44313/api/Rentals?start=1&limit=25

I would recommend to use this approach rather than a non standard REST API. It will enable you to use Ext's related features seamlessly.

If there is no way to change the API and you need to stick with your current server configuration then you need to create a custom proxy overriding some of the related functions. The best bet if you override the buildUrl function and pass your custom generated URL to the request object.

UPDATE

You can start with this code (also created a Fiddle):

Ext.define('Yournamespace.proxy.custom', {
        extend: 'Ext.data.proxy.Rest',
        alias: 'proxy.custom',
        buildUrl: function(request) {
            const url = this.callParent([request]);
            const operation = request.getOperation();
            console.log(url, this.getParams(operation))
            return url;
        }
    });
    
 Ext.define('User', {
     extend: 'Ext.data.Model',
 });

 
Ext.application({
    name : 'Fiddle',
    launch : function() {
    var myStore = Ext.create('Ext.data.Store', {
         model: 'User',
         pageSize: 10,
         proxy: {
             type: 'custom',
             url: 'https://localhost:44313/api/Rentals/',
             reader: {
                 type: 'json',
                 rootProperty: 'users'
             }
         },
         autoLoad: true
     });
    }
});

You can write your custom code to the buildUrl function. Currently only the default URL and the params are collected and logged there but it does the default stuff. You can tweak the URL here and return the new URL at the end.

Sign up to request clarification or add additional context in comments.

6 Comments

Can you show or teach me how I could do a custom proxy for overriding and how I can call it from the view controller when changing pages. I am still a beginner on ExtJS so a snippet would greatly help. Thank you.
I assume it means there is no way to change the API to use proper REST parameters :). I will update my answer as soon as time permits.
Added an example for you to overwrite the buildUrl function. Enjoy. :)
I completely agree with using standard REST API. Can you tell me how to change the page with this URL: localhost:44313/api/Rentals?start=1&limit=25 from a grid?
I'm not sure I understand your question. Please provide more details.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.