Search code examples
angulartypescriptangular-routingangular-services

Data from api is diplayed only after refreshing the pages in angular


I'm new to angular and I was working on an angular project. There is a problem I'm facing is that, after each component routing the data from is not displayed at first but after reloading the page the data is displayed as shown here before reload

[![after reload][2]][2].

and [2]: https://i.sstatic.net/Wn3Bv.png

the code used in service is

import { Injectable, SimpleChange } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { DatePipe } from '@angular/common';
import { environment } from 'src/environments/environment';

import { RouterModule, Routes, ActivatedRoute, Router } from '@angular/router'
@Injectable({ providedIn: 'root' })
export class UserService {
    public userList = [];
    public userData = [];
    public header: any;
    public userkeypair: any;
    constructor(private http: HttpClient,
        private router: Router) {

        this.header = new HttpHeaders()
            .set("Authorization", 'Bearer ' + JSON.parse(localStorage.getItem('token')));
    }
    ListAlUsers() {
        this.http.get<any>(`${environment.apiUrl}GetAllEndUsers`, { headers: this.header })
            .pipe(map(rese => {
                return { rese }
            }))
            .subscribe((result: any) => {
                this.userList.push(result);
                this.userData = this.userList[0].rese;
                var stst: any;
                var useraary:any=[];
                for (let i = 0; i < this.userData.length; i++) {
                    if (this.userData[i].status == "True") {
                        stst = "Active";
                    } else {
                        stst = "Inactive";
                    }
                    this.userkeypair = {
                        "id": this.userData[i].id, "name": this.userData[i].fullName, "email": this.userData[i].emailId, "account": this.userData[i].relatedAccount,
                        "status": stst
                    }
                    useraary.push(this.userkeypair);
                }
sessionStorage.setItem('userlist',JSON.stringify(useraary));
            });
    }

}

and the component.ts is

import { Component, OnInit } from '@angular/core';
import{UserService} from './user.service';
@Component({
  selector: 'app-user',
  templateUrl: './index.component.html',
  styleUrls: ['./index.component.css']
})
export class userComponent  {
public Userlst=[];
  constructor(private UserService:UserService) { 
    this.UserService.ListAlUsers();
    this.Userlst=JSON.parse(sessionStorage.getItem('userlist'));
  }

  

}

please help me with this


Solution

  • James, your service shoud return observables, and you subscribe in component. If you want to make "something" with the response in service, use "tap". e.g.

    NOTE:map is to transform the response, if you don't transform, not use it

    ListAlUsers() {
       //see that you use "return"
       return this.http.get<any>(`${environment.apiUrl}GetAllEndUsers`, { headers: this.header })
                .pipe(tap(rese => {
                   ..make what ever with the response..
                   ..well, the code you has in subscribe...
                 }
    

    In your component

    //see that you equal this.Userlst IN the subscribe function
    this.UserService.ListAlUsers().subscribe(_=>{
        this.Userlst=JSON.parse(sessionStorage.getItem('userlist'));
    }
    

    NOTE:You storage the value in SesionStorage, really you need'nt if you don't want that the value is maintein between sessions

    Update about not in SessionStorage. We want the service return a data like useraary. So we use "map" to transform the value

    ListAlUsers() :Observable<any>{ //<--I indicate thar return an Observable
       //see that you use return this.http.., yes! we return an observable
            return this.http.get<any>(`${environment.apiUrl}GetAllEndUsers`, { headers: this.header })
                .pipe(
                .map((result: any) => {
                    //map can be so complex as we want
                    this.userList.push(result);
                    this.userData = this.userList[0].rese;
                    var stst: any;
                    const useraary:any=[]; //<--NOT use var, use const or let
                    for (let i = 0; i < this.userData.length; i++) {
                        //I use a ternary operator instead an if
                        const stst=(this.userData[i].status == "True")?"Active":"Inactive"
                        this.userkeypair = {
                            "id": this.userData[i].id, "name": this.userData[i].fullName, "email": this.userData[i].emailId, "account": this.userData[i].relatedAccount,
                            "status": stst
                        }
                        useraary.push(this.userkeypair);
                    }
                    //and we simply return the value
                    return useraary;
                });
        }
    

    In our component

    this.UserService.ListAlUsers().subscribe(response=>{
        this.Userlst=response
    }