amplitude / redux-query

A library for managing network state in Redux
https://amplitude.github.io/redux-query
Other
1.1k stars 67 forks source link

Question: Maintaining API ordering #21

Closed azappella closed 7 years ago

azappella commented 7 years ago

Hi there,

First off, thanks for the library!

Given that your Async Example uses normalizr, I thought my question might be relevant. Normalizr uses the "result" key to maintain the order of the data that is normalized. Using redux-query, how would you maintain that ordering without somehow passing/storing the "result" object? In your example, you only pass the "entities" down, so it seems the ordering is lost. I guess it would be up to the user to somehow store that result object or reorder the entities in the transform method before passing them further:

const ProductsContainer = connectRequest((props) => ({
    queryKey: QUERY_KEY,
    url: `${CONFIG.BACKEND.api_url}/product-catalog`,
    transform(response) { 
        const normalized = normalize(response.products, [productSchema]);

        // Here you could somehow sort based on the result key and then merge and pass it down further. 
        // But, it would be much better to have it in mapStateToProps. 
        // const sortedProducts = normalized.result.map(id => _.get(normalized.entities.products, id));

        return normalized.entities;
    },
    update: {
        products: (prevProducts, products) => {
            return { ...prevProducts, ...products, success: true  };
        },
        productRatePlans: (prevProductRatePlans, productRatePlans) => (
            { ...prevProductRatePlans, ...productRatePlans }
        ),
        productRatePlanCharges: (prevProductRatePlanCharges, productRatePlanCharges) => (
            { ...prevProductRatePlanCharges, ...productRatePlanCharges }
        ),
    },
}))(Products);

For reference: https://github.com/paularmstrong/normalizr/issues/9

From the redux without profanity book:

Normalizr places your data inside an object within entities. Unfortunately JS objects do not guarantee any specific order. If you're normalizing a search result, for example, this might completely break the search results you display.

To maintain the order of data from the API you must iterate through the result property of the normalized object. This is an array which lists the IDs of entities from the search result. And arrays safely guarantee the order of its values.

Thanks & hope it's somewhat relevant.

ryanashcraft commented 7 years ago

Thanks!

The normalizr schema we use for the async example uses arrayOf for normalizing the subreddit posts: https://github.com/amplitude/redux-query/blob/e8459abdfc55515a3e79c812723aafa9f470863a/examples/async/containers/App.js#L101

If you look at the console, you can see how the posts are stored as a list of IDs inside the reddits entities. This list determines the order and each ID can be mapped to a post in the posts entity:

screen shot 2017-02-23 at 9 30 16 am

Please correct me if I am misunderstanding your question. :)

azappella commented 7 years ago

Yes, thank you for your response!