I'm trying to pass the data of an Observable retrieved by API request to a component variable in order to display it but I just can't make it work. Please help, here is my code. Regards,
TypeScript Service : Request to API to get Observable
export class ServeurService {
serverCharacter = 'https://cegep.fdtt.space/v1/characters';
serverSecret = 'https://cegep.fdtt.space/v1/secret';
personnages: any[] = [];
persoName = '';
constructor(private http_client: HttpClient) { }
getPersonnage(): Observable<ICharactere[]> {
return this.http_client.get<ICharactere[]>(this.serverCharacter).pipe(retry(4));
}
getAllInfosById(id: string): Observable<ICharactere> {
const myUrl = 'https://cegep.fdtt.space/v1/character/' id;
return this.http_client.get<ICharactere>(myUrl)?.pipe();
}
setPersonnageName(name: string) {
this.persoName = name;
}
getPersonnageName():string {
return this.persoName;
}
getPersonnages() {
this.http_client.get<any>('https://cegep.fdtt.space/v1/characters').subscribe({
next: (val) => {
val.data.forEach((element: { data: any; }) => {
this.personnages.push(element);
});
}
});
return this.personnages;
}
getPersonnageById(id: string) {
const persoSelectionne = this.getPersonnages().find((x: { id: string; }) => x.id === id);
return persoSelectionne;
}
getPersonnageIdByName(name: string) {
const persoSelectionne = this.getPersonnages().find((n: {name: string; }) => n.name === name);
console.log("perso name service", persoSelectionne)
return persoSelectionne.id;
}
TypeScript Component : Passing the Observable to a variable
export class StatsComponent implements OnInit {
myCharactere!: any;
statLookup = [
{ key: 'str', prefix: $localize`str`, suffix: $localize`enght`, couleur: 'bg-danger' },
{ key: 'dex', prefix: $localize`dex`, suffix: $localize`terity`, couleur: 'bg-primary' },
{ key: 'con', prefix: $localize`con`, suffix: $localize`stitution`, couleur: 'bg-warning' },
{ key: 'int', prefix: $localize`int`, suffix: $localize`elligence`, couleur: 'bg-success' },
{ key: 'sag', prefix: $localize`wis`, suffix: $localize`dom`, couleur: 'bg-info' },
{ key: 'cha', prefix: $localize`cha`, suffix: $localize`risma`, couleur: 'bg-dark' }
];
constructor(public myService: ServeurService) { }
ngOnInit(): void {
this.myService.getAllInfosById(this.myService.getPersonnageIdByName(this.myService.getPersonnageName())).subscribe(result => {
this.myCharactere = result
});
console.log("stats component perso", this.myCharactere)
}
getModifier(stat: number): string {
const mod = Math.floor((stat-10)/2)
return (mod<0)?'-':' ' mod.toString();
}
}
HTML : Displaying the variable
<div >
<div >
<div *ngFor="let stat of statLookup">
<div >
<div >{{stat.prefix}}<span >{{stat.suffix}}</span>
</div>
<div >
{{myCharactere && myCharactere.statistics && myCharactere.statistics[stat.key] ? getModifier(myCharactere.statistics[stat.key]) : ''}}
</div>
<div >
{{myCharactere?.data.statistics[stat.key]}}
</div>
</div>
</div>
</div>
If it helps, here is the model too :
export interface ICharactere {
error: string;
data: {
id: string;
name: string;
statistics: { [ key : string ]: number }
race: string;
player: string;
classe : string;
sousclasses: string;
level: number;
background: string;
synopsis: string;
image: string;
health: number;
currentHealth: number;
traits: {
trait: string;
description: string;
}[];
// Should be computed
armorClass: number;
initiative: number;
speed: number;
};
}
CodePudding user response:
You have some fundamental concepts mixed up here. First, you're calling getPersonnages() synchronously and it is making an HTTP call which is an asynchronous operation. I understand what you're trying to do, but if you are going to use observables for your search result, then I suggest you make all of your function calls consistent that way. Here's an example:
getPersonnages(): Observable<any> {
return this.http.get<any>('https://cegep.fdtt.space/v1/characters');
}
getPersonnageIdByName(name: string) {
return new Observable(observer => {
this.getPersonnages().subscribe(
(results => {
observer.next(results.data.find(x => x.name === name))
observer.complete();
})
)
})
}
Now you can search for the ID value you want like this:
this.getPersonnageIdByName("Michel Michaud").subscribe(
(searchResult => {
// here I can get the id
const id = searchResult.id;
})
);