Search code examples
angularangular5angular-servicesangular-data

Angular 4/5 : Share data between Angular components


In my angular app, when I login in to the app, I get an access token which I need to use it in my API calls in other components (not parent/child relationship). I tried using Shared service but it's not working

Data Service:

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs/Subject';

@Injectable()
export class DataService {

  private userInfo = new Subject<any>();
  currentuserInfo$ = this.userInfo.asObservable();

  constructor() { }

  updateUserInfo(message: any) {
    this.userInfo.next(message)
  }

}

In my login component I have

this.dataService.updateUserInfo(data.userToken);

Other Component

this.dataService.currentuserInfo$.subscribe((data: any) => { 
  console.log(data);
});

Here I am unable to get the tocken that was updated with the login component.

In the shared Service I tried both Subject and Behavior Subject but both didn't work.

I made sure that I just mentioned this DataService as a provider only in app.module.ts. I didn't mentioned it in login component or in any other component


Solution

  • the best way to add token in requests is to use interceptor

    import { Injectable, Injector, EventEmitter } from '@angular/core';
    import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    import { AuthService } from '../services/auth.service';
    
    @Injectable()
    export class HttpsRequestInterceptor implements HttpInterceptor {
        private actionUrl: string;
    
        constructor(
            private injector: Injector
        ) {
            this.actionUrl = 'https://test.com/dev';
        }
    
    
        intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
            const _req = {
                url: this.actionUrl + req.url,
                headers: req.headers.set('Content-Type', 'application/json')
            };
    
            const user = this.injector.get(AuthService).getAuthenticatedUser();
    
            if (user) {
                user.getSession((err: any, session: any) => {
                    if (session) {
                        const token = session.getIdToken().getJwtToken();
                        _req.headers = req.headers
                            .set('Content-Type', 'application/json')
                            .set('Authorization', token);
                    }
                });
            }
    
            return next.handle(req.clone(_req));
        }
    }
    

    UPDATED:

    if you need to create a shareable service - you can try to use the behavior subject. Please look at this example

    UPDATED2:

    if you want to use shareable data in spite of the page refreshing - you should use localstorage:

    localStorage.setItem('str', 'whatever string'); // set string
    localStorage.setItem('obj', JSON.stringify(obj)); // set object
    const str = localStorage.getItem('str'); // get string
    const obj = JSON.parse(localStorage.getItem('obj')); // get object
    const str = localStorage.removeItem('str'); // remove