I am a beginner in Angular (12) and I am struggling with this issue. I want to display more than one random quote on a page. I've managed to display multiple, but they are all the same underneath eachother. I have no errors in the code. I have tried some forEach but couldn't do it. Here is the code:
app.component.html
<div class="main-content">
<div class="joke-wrapper" *ngFor="let joke of jokes">
<div class="joke">
<p>{{ joke.value }}</p>
</div>
</div>
<div class="joke-wrapper" *ngFor="let joke of jokes">
<div class="joke">
<p>{{ joke.value }}</p>
</div>
</div>
</div>
jokes.service.ts:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root',
})
export class JokesService {
private apiUrl = 'https://api.chucknorris.io/jokes/';
constructor(private http: HttpClient) {}
getRandomJoke() {
return this.http.get(this.apiUrl 'random');
}
}
app.component.ts:
import { Component, OnInit } from '@angular/core';
import { JokesService } from './jokes.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
jokes: any[] = [];
constructor(private jokesService: JokesService) {}
ngOnInit() {
this.jokesService.getRandomJoke().subscribe((joke) => {
this.jokes.push(joke);
});
}
}
CodePudding user response:
The problem is that your array only contains one joke.
This probably works.
import { Component, OnInit } from '@angular/core';
import { JokesService } from './jokes.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
jokes: any[] = [];
constructor(private jokesService: JokesService) {}
ngOnInit() {
// Multiple times
this.addJoke();
this.addJoke();
}
addJoke() {
this.jokesService.getRandomJoke().subscribe((joke) => {
this.jokes.push(joke);
});
}
}
Although I would prefer this solution:
Making use of the async
pipe can get some performance gains and it is generaly cleaner code.
component ts:
import { Component, OnInit } from '@angular/core';
import { JokesService } from './jokes.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
jokes$!: Observable<any[]>;
constructor(private jokesService: JokesService) {}
ngOnInit() {
this.jokes$ = this.jokesService.getRandomJokes(10);
}
}
Service ts:
@Injectable({
providedIn: 'root',
})
export class JokesService {
private apiUrl = 'https://api.chucknorris.io/jokes/';
constructor(private http: HttpClient) {}
getRandomJoke() {
return this.http.get(this.apiUrl 'random');
}
getRandomJokes(amount: number) {
const jokes = [];
for (let i = 0; i < amount; i ) {
jokes.push(this.getRandomJoke())
}
return forkJoin(jokes);
}
}
component html:
<div class="main-content">
<div class="joke-wrapper" *ngFor="let joke of jokes$ | async">
<div class="joke">
<p>{{ joke.value }}</p>
</div>
</div>
</div>