Angular, how to display more than one random quote on one page?

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);
 });
}
}

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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>


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x