In my angular application, I have to transform some data from backend API. The problem is that some fields need to be assigned with data from the server either.
For example, I have a client (it's a simplified example):
{
id: 1122,
firstname: 'John',
lastname: 'Doe',
countryId: 12
}
There is a country ID. I want to get country name from the server by the ID.
I have used asynchronous angular pipes in template that returns Observable with country name string:
<h3>{{ client.countryId | countryAsyncPipe | async}}</h3>
But I need data not only in the templates.
So, how do I resolve this kind of a problem?
Thank you!
UPDATE:
I'm sorry, I haven't provided enough information in the question. I will try to explain what I mean with some hypothetic example.
First of all, I.ve forgot to say that I'm trying to create DTO. I've got an API Service, for instance, ClientHttpService:
@Service()
class ClientHttpService extends Http {
findAll(): Observable<Array<Client>> {
return this.get(this.url).pipe(
map(client => clientSerializer.fromJsonFactory(client))
);
}
}
I receive JSON clients and create instances of ClientModel (not necessary, it may be a literal object) with serializer service:
class Client extends Model {
id: number;
firstname: string;
lastname: string;
countryName: string;
constructor({ id, firstname, lastname, countryName }) {
//...set object properties
}
}
@Service()
class ClientSerializer implements Serializer {
public fromJson(data: any): Client {
return new Client({
id: data.id,
firstname: data.firstname,
lastname: data.lastname,
countryName: data.countryId // trouble
});
}
public fromJsonFactory(data: Array<any>): Array<Client> {
return data.map(client => this.fromJson(client));
}
}
Well, here is a problem. I really don't understand how to provide the country name. Let's say, I've got CountryService:
@Service()
class CountryHttpService extends Http {
findNameById(id: number): Observable<string> {
return this.get(`countryUrl`).pipe(map(country => country.name));
}
}
How could I correctly provide result into my Serializer if it returns Observable?
return new Client({
//...
countryName: countryService.findNameById(data.countryId) // Observable, not string
});
You need to subscribe()
or toPromise().then()
in order to get the desired data within your .ts file.
For example, let's say you have a CountryService with a method
getCountryName(countryId: number): Observable<string> {
return this.http.get<string>(your endpoint);
}
In the component that you want to fetch the countryName you should inject your service and:
this.countryService .getCountryName(countryId).toPromise().then( (countryName: string) => {
// transform your data here
});
or replace toPromise().then()
with subscribe()
.
UPDATE:
public fromJson(data: any): Client {
this.countryService.findNameById(data.countryId).subscribe((countryName: string) => {
return new Client({
id: data.id,
firstname: data.firstname,
lastname: data.lastname,
countryName: countryName
});
});
return null;
}