Can you update firestore query dynamically based on router location? - reactjs

So basically, I have a simple React app connected to Firebase that lists different types of food from firestore collections.
Example:
I have a few categories. The default one is "All" that displays top 8 popular dishes from all other available categories and this part is easy but I want an user to be able to click on other category and update my query.
Category is actually a NavLink that updates location on click so: if user click on "Pizza" category the url looks like this localhost:3000/Pizza if he clicks on Salad it is localhost:3000/Salad etc.
I have a "Wall" component that is a section and it displays those items from firestore.
My query ref in this wall component look like this: const foodRef = db.collection("food").doc("all").collection("items");
But I want to set .doc dynamically and make query on every update so I changed the query to something like that:
const location = useLocation();
const foodRef = db.collection("food").doc('${location.pathname}').collection("items");
And when user click on different Card (NavLink) url updates but query does not.
I know it is a bad solution but I actually have no idea how to do that.
I have read about Recursive Paths in react router but I do not know if it is what I am looking for.
If you know how to approach that please let me know.
Thanks for your time.

Firestore does not support wildcards or replacements in queries and Query objects are fully immutable (they can't be changed). You have to know the names of the documents and collections ahead of time to build a query. If you want to change some part of a query, you have to rebuild a whole new query object every time, and run the query again to get a new set results.

Related

Structuring the Firestore: Should I make another collection to store the changes that were made?

I am using Reactjs and Firestore.
I have this collection of products:
The colorMap is a map then below it are the different colors and their quanty.
Now, I want to create a list or a history whenever a product is added and whenever the quantity in those colors was added more of it.
Should I add another collection that will store when a product is added or whenever quantities are added in the color? I'm also thinking of adding a createdDate
Or there any other way I could do this? As much as possible, I won't be using any cloud functions.
A common way to keep the history of each document is by creating a subcollection under that document (say history) and writing a new document with either the complete, old document data there for every update you perform, or a new document with just the old values of the fields that were modified.
While it is convenient to do this from Cloud Functions, as they already get both the previous and the new data for each document write, you can accomplish the same from client-side code too.

React-Redux Fetch data from api, search and lazy loading

I have a list of data which are rendered by default (20 items) with lazy loading functionality (pagination) to load more data when the user scrolls to a certain position.
Now I need to implement a search functionality from the api itself, my question is:
Initially I have 20 items, when a user search they will get another 20 items based on the search term (the old set will be replaced), and when scrolling they will get page 2 from the list based on the search term.
So what is the best practice here to know when I need to concatenate the old data with the new batch or to replace the old set of data with a new one.
My question is more architectural, any help would be appreciated.
Because backend shall has paginator in search, you only would re render component with new information in such page(bit collection), in other words , if you has service backend pagination render "item component", if you search into a collection(javascript array) in browser , use "collection/list component" (map), you can use keys to property change

Redux Structure Advice

I've built a few React Native apps with Redux and I've traditionally modeled my state after the views/ui. I've come to realize that this isn't the best way to organize Redux state.
Through some recent research, I know now that it's best practice to not store duplicate data in different reducers, as updating them can become tedious. It's better to store data in objects with the keys being the id and the value being the data object itself.
This makes sense for data that will be the same on every screen/page, but what if your app uses the data differently on different screens?
For example:
I have a list of products on a home screen and a list of products on a category screen. Both have pagination and are looking at different subsets of the product data. I could use a selector method here and only select products belonging to the specific category on the category screen, but how would that work with keeping track of pagination data for each one?
If I scroll down on the home screen and load a bunch of product data, then switch to the category screen, I'll have more data already loaded.
Any advice is appreciated, thanks!
You should normalize your data (https://github.com/paularmstrong/normalizr) so you can have your redux state like:
{
home: [...list_of_id_products],
category: [...list_of_id_products],
data: [actual_array_of_objects]
}
then you can have separated lists, all linked to the same set of data

How to do search operation with #ngrx store?

I have a contacts collection (contacts of all employees) in my angular app. It is similar to any contacts or address app where there are contacts and you can search for a name. When the search is done for a name like 'John', the app should show only names having 'John'.
The contacts are saved already in the MSSQL DB.
My question is about how should I manage the state with #ngrx store?
Should I read all the contacts from the MSSQL DB when the app starts and then do the name search in the #ngrx store with a reselect selector to get the search results?
Should I do the search in the MSSQL DB and then clear and load the #ngrx store with the search results every time when the search is done?
2nd option, of course.
there is no point in downloading all the data.
you should have searchResults part of the store, update it on every search and do store.select(reducer.getSearchResults) to show it in your components.
if you would follow the same logic throughout the whole app with loading every piece of data you could ever need in your app lifetime you would end up with useless app very quickly ;)

React router - different content if post in list vs own page

React router has very cool feature: if you have a list of items (Instagram for example) and if you click on one item, content opens in modal/overlay but if you copy-paste the link to new tab/window or share the link with a friend for example, it opens in its own page.
I would love to use this feature but I need to find a custom solution..
My posts are very data heavy
I've split posts data into 2 tables in database
1st is very lightweight containing essential data: 4-5 columns
2nd table is very heave, ~30 columns
When user uses search filter, list updates only with data from 1st table
If user clicks on post, it will open in a modal/overlay
I will recycle the data I already have (from 1st table) and also get rest of the data from 2nd table
However, when user shares the link or opens it in new tab/page, data from 1st table is not present. I would need to integrate a conditional logic:
If post opens in list view (modal/overlay), only get additinal 2nd table data
If it's opened in a new tab/window in its own page, get all the data, 1st table included
How could I integrate this with React router? Has anyone already tried it? This would also allow to use different layout/components when user opens item in page view. Is there a way to check it?
Or is there a flaw in my logic? I imagine list would update very fast because it doesn't require huge amount of data and also would modal/overlay because it recycles some of the data.
I read all the docs, also searched online - didn't find anything.
Modals in react router are great. I've used the pinterest example and adapted it to my own needs.
Ensure you do your check on state.modal===true in a master layout component to give you the modal styling.
you'll need to check if table 1 stuff is present in your state and dispatch an action to trigger the async call in componentDidMount. You should be fetching table 2 in all scenarios.

Resources