#NgRx entity relations (how)

41 messages · Page 1 of 1 (latest)

slender seal
#

Hi, I have a question about Many to Many as well as One to Many relationships in NgRx.

Would it be better to keep every entity separated and store them in their own State (for Example, User Model has many Note Models, and Note has one User), keep a separate User and Note state and couple them together in the selectors? (I assume so..)

Also, when calling the API I use, getting all Users doesn't return all their notes. I have to get the User by Id to get all the user along with all their notes, or call the notes endpoint explicitly.
Same principle applies with Many to Many relationships in this API.

What I am struggling with is, I don't really know how I can tie all entities with relationships together, the right way.
When I use a selector, it won't check if entity with id X actually exists in the current store.
I can't get 100 users with 4000 notes from the API for example. So I may have 10 users with 0 notes, but I want to do an API request to get the notes that belong to those users or the ones I want to interact with.

So if I have a list of 10 users displayed (serverside pagination), and I click on one to get all their notes, I would have to dispatch an action (getUserWithNotes or something?) where Users are stored in User state and Notes in Note state and then selectUserWithNotes where a Note(from note state) its userId is equal to the user I want to get(from user state).

And with many to many, how would I do that? For example, this time, user has many notes AND note has many users. (So there is a different object in between those 2, named UserNote for example)
In what state do I store the many to many relationship? Should it have its own state? and how would I make a selector for this?

Please let me know if I'm thinking wrong or if I'm doing it wrong and the way it should be done. Thanks!

lavish lake
#

(1) I imagine that the GUI is designed to display users and their associated notes.
so I will recover the whole and why not with a paginator that recovers by batch of 10

#

(2) the other case is that you first display the users and then if you click to see it, the notes appear.
in this case I will recover only the users without the notes and at each selection of user I recover his notes

#

(3) possible to make the same graphic system as (2) but without recovery time.
then we recuperate everything and display the notes as needed

lavish lake
slender seal
#

I guess getting all notes with the users wouldn't hurt if it's paginated yeah.. However, do I store the Notes in the state as children of the User? Or keep them in a seperate state?

And how would I do that if it's many to many?
Having the Notes as children of the User, or the other way around, wouldn't be possible (or very inefficient) if I have multiple notes that belong to multiple users, and I'd have to update them clientside.

#

I would HAVE to have them in a seperate state I think, I got an idea now how I would do that for one to many relationships. But I still don't really know how I would do it for many to many. Would I just have the middle object which connects the note and users together as a seperate state?

lavish lake
#

why this two-way relationship?

you want :
(1) display the users with their notes
(2) display a note and the users who had this note

is that why ?

you have to think about the features your application has to provide

slender seal
#

I gave the User and Note model as examples to state what I want to achieve, I don't actually have Users with Notes, but I thought it was easier to explain it with those names.

#

Maybe easier models to explain it with would be... I have a book, and a book as multiple authors, but authors have multiple books as well..

lavish lake
#

my question is, do you need both ways? or is one way enough?

slender seal
#

I need both ways yes

lavish lake
#

I collect the books and authors in one batch.
then if I need to know the authors who wrote books I will do a query with RxJS on the whole batch to extract the authors of the book.

with RxJS we can do with elegance this kind of treatment

#
  • so a single source and you apply RxJS processing for the other special cases
slender seal
#

What do you mean collect books and authors in one batch? As in one request to the API?
And then save books in book state and authors in author state?
but then how do I know which books belong to a certain author || which authors belong to a certain book?
I would have to save their relation somewhere right? (BookAuthor) which defines authorId with a bookId. Is that a state as well?

lavish lake
#

I'm getting this:

json

[
    {
        "ID": "...",
        "title": ".......",
        "authors": [ 
                {
                    "ID": "...",
                    "name": "...x"
                }
               ]
    },
    {
        "ID": "...",
        "title": ".......",
        "authors": [ 
                {
                    "ID": "...",
                    "name": "...y"
                },
                {
                    "ID": "...",
                    "name": "...z"
                },
                {
                    "ID": "...",
                    "name": "...x"
                }
               ]
    },
]

with RxJS I can make a treatment that retrieves all the books whose author is "...x" for example

#
  • since the authors are included in a book I know who is related to what
slender seal
#

In the backend it is defined as:

Book:

{
  "Id": "36d5f70c-32aa-4560-b176-5435b154d4ba",
  "Name": "Hunger Games"
}

Author:

{
  "Id": "bbbba8bf-e1f5-4aaa-915f-2034771fe94f",
  "Name": "Nick is Hero"
}

BookAuthor:

{
  "Id": "a26b7243-0044-43e4-9f21-db11da2e3a3c",
  "BookId": "36d5f70c-32aa-4560-b176-5435b154d4ba",
  "AuthorId": "bbbba8bf-e1f5-4aaa-915f-2034771fe94f"
}
lavish lake
#

you have access to the back ?

slender seal
#

It's a postgresql database with standard entity relations

#

ye

lavish lake
#

normally the back should return the format I indicated with the json above

#

you have to manage to make this kind of returnyou have to manage to make this kind of return

slender seal
#

that's one to many

#

that's not many to many

lavish lake
#

no matter
it's up to you to write a query in the back to group, usually you have to use a join

slender seal
#

Book:

{
  "Id": "36d5f70c-32aa-4560-b176-5435b154d4ba",
  "Name": "Hunger Games"
}

Author:

{
  "Id": "bbbba8bf-e1f5-4aaa-915f-2034771fe94f",
  "Name": "Nick is Hero",
  "Books": [
    {
      "Id": "36d5f70c-32aa-4560-b176-5435b154d4ba",
      "Name": "Hunger Games"
    }
  ]
}

that would be one to many

slender seal
#

I could make a DTO yeah

lavish lake
#

select book join author ON ............

slender seal
#

I use entity framework

lavish lake
#

something like that 😉

#

yeeah good !

slender seal
#

alright ill dig into it some more ty

lavish lake
#

with postman try that you get this format well

#

it is necessary to make only one source because after imagine you modify a place
with several sources you have to modify everywhere, it will be complicated and source of error.

so one source, that we update and we make treatments. this is the good practice

good luck

slender seal
#

to add on to it....

  • One of the reasons why Book|Author is many to many, is because books can have multiple authors and authors can have multiple books.
  • Another reason why I actually cannot nest books into an author, or an authors into a book, is because I will have duplicates (Same author can exist in a multiple books and vise versa). So I NEED it in separate states.
  • Another thing is that I want to show a list of authors without their books, but with a click it shows their books.
    Same the other way around. I want to show a list of books, maybe this time immediately with their authors.

So that means I cannot nest authors in books or vise versa. so I really need that BookAuthor model in between, the one I mentioned a bit above.. perhaps in a separate state? or how?? this was my initial question

#

As a general rule of thumb, you shouldn’t have big arrays for entity types in the store and instead create an Entity map using NgRx entity(https://ngrx.io/guide/entity). Entity maps are simply key-value pairs with unique entities. Having data organized this way makes reading and updating fast and that is what we want to optimize for.

I think this is what I need, to implement NgRx entity to map all relations together with what ids in the store they belong to.

#

If anyone could confirm this, please let me know

lavish lake
#

normalized store, is it the same source ? (users + comments)
is that right ?