jeudi 12 septembre 2019

How best to handle nested requests in an angular model without waiting for nested requests to complete

The API for our Angular application has a lot of nested objects referred to by hrefs. I'm trying to map all of these responses to models to get some decoupling between backend and frontend. However, I've come across a problem with these nested hrefs.

Here is an example response from the server:

First response:
{
    "firstName": "Steve",
    "lastName": "Mcqueen",
    "account": "api/path/account/some-id-key"
}


My issue is: how do I handle the request to fetch the account. There can be 3-4 of these in some cases (or worse, nestled 2-3 levels deep) and I don't always need that data right away. Preferable the request would be handled by a service (AccountService in this example).

I've considered a few approaches. The first and laziest is to in the model simply store the href as a string and fetch it where it is needed.

class Client {
    firstName: string;
    lastName: string;
    account: string;
}

// in a component
this.clientService.getClient(id).subscribe(client => {
    this.accountService.getAccount(client.account).subscribe(...)
})

However, I fear this will get quite messy. Four different components might now be doing the same request at the same time every single time client is updated. It is also not very nice looking having these subscribe-masses everywhere.

Secondly, I thought about letting the service do all the fetching using tap, switchmap like in this answer.

The problem here is that I have to wait for every single request in the model to be resolved before I can start showing any data. If it is like the example above that is fine, but that is not always the case.

Best case would be if I could somehow let the model have Observables instead of the hrefs. So the client model would look something like

class Client {
    firstName: string;
    lastName: string;
    account: Observable<Account>;
}

// in a component
this.clientService.getClient(id).subscribe(client => {
    client.account.subscribe(...) // no more duplicated requests
})

// In the model adapter
adapt(data) {
    return new Client(
        data.firstName,
        data.lastName,
        this.accountService.getAccount(data.account)
    )
}

I am struggling with how I would best map this, however. Since each request creates a new Model, it would end up with a leak since the "old" models wouldn't be unsubscribed. Unless somehow the service would reuse the same observable for the same model href maybe?

Aucun commentaire:

Enregistrer un commentaire