NJ.
NJ.

Reputation: 7606

Ngrx server sided pagination with router parameters

I have a store with a simplified state tree:

{
    routerReducer: {
        state: {
            url: '/blog'
        },
        queryParams: {
            category: 'home'
        }
        params: { }
    },
    blog: {
        posts: {
            entities: { ... }
            loading: false,
            loaded: false,
            pagination: {
                sort: 'date',
                filters: {
                    category: 'home',
                    tag: 'testTag'
                },
                page: 1
            }
        }
    }
}

Basically, I'd like to pass down my router state into my blog state for pagination purposes, but only if the current URL belongs to that module if that makes sense? The pagination part of my blog -> posts state will be based on the URL parameters, already composed in my state. Perhaps this is not the correct method as I will no longer have a single source of truth? But I'd like to use this pagination state to essentially describe the set of entities I have in my store. That means, if I move pages or change filters, I plan on clearing all entities and refreshing with paginated content (performed server-side) from my API.

I supposed my flow will look like this:

How does this flow sound? Is this the correct way of doing this?

Upvotes: 0

Views: 1028

Answers (1)

MTJ
MTJ

Reputation: 1097

1) It sounds feasable.

2) No. Whatever gets the job done.

What I would do

I'd create blog postPagination state where I would keep pagination data separate from entities. And a BlogPaginate action to alter it's state in reducer function.

{
   {
        sort: 'date',
        filters: {
            category: 'home',
            tag: 'testTag'
        }
    },
    page: 1
}

I'd make an effect that listens on router actions and maps the matching ones (url /blog/*) with appropriate search filters to BlogPaginate action which in turn would trigger a service call.

If you'd like to cache those entities

Making moving back to pages you've seen previously would be smoother than before. Depending on your content change rate I'd choose to either dispatch an action or just use the value in the cache if it exists.

Then I would add to postPagination state:

{
   pageContents: {
      // map of page to entity ids
      1: [1,8,222]
   }
   {
        sort: 'date',
        filters: {
            category: 'home',
            tag: 'testTag'
        }
    },
    currentPage: 1,
    totalPages: 10
}
  • When pagination filters / sort changes in BlogPaginate reducer I would clear pageContents.
  • When pagination response's totalPages changes in BlogPaginateSuccess reducer I would clear other pageContents pages.
  • In BlogPaginateSuccess reducer I'd add/update new entities in blog posts and map their id's in as pageContents. Remember reducers can react to what ever action.
  • I would also create a selector that maps postPagination.currentPage, postPagination.pageContents and post.entities into an array of blog post entities.

Upvotes: 1

Related Questions