Using Angular 6 to Share Data Among Components through Services

I am facing an issue in my home component, which is a child of the Dashboard component. The object connectedUser injected in layoutService appears to be undefined in the home component (home userID & home connectedUser in home component logs); Is there something missing here?

home.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HomeRoutingModule } from './home-routing.module';
import { HomeComponent } from './home.component';

@NgModule({
    imports: [
          CommonModule,
          ReactiveFormsModule,
          HomeRoutingModule,
          FormsModule
    ],
    declarations: [
        HomeComponent
        ],
    providers: [

    ]
  })
  export class HomeModule {}

dashboard.component.ts

import { Component, OnInit } from '@angular/core';
import { UserConnected } from 'src/app/models/userConnected';
import { LayoutService } from '../services/layout.service';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {

  currentDate: String;
  userSaml = new UserConnected();
  constructor(public layoutService: LayoutService) { }

  ngOnInit(): void {
  
    var today = new Date();
    this.currentDate = today.getDate() + '/' + (today.getMonth() + 1) + '/' + today.getFullYear();

    this.layoutService.getConnectedUser().subscribe(

      (data) => {
        this.userSaml = data;
        this.layoutService.connectedUser.matricule = this.userSaml.matricule;
        this.layoutService.connectedUser.profil = this.userSaml.profil;
        this.layoutService.connectedUser.uid = this.userSaml.uid;
        this.layoutService.connectedUser.username = this.userSaml.username;
        this.layoutService.connectedUser.city = this.userSaml.city;
      },
      (err) => {
        throw err;
      }
    );

  }

}

app-routine.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AppComponent } from './app.component';
import { DashboardComponent } from './shared/layout/dashboard/dashboard.component';

export const routes: Routes = [
  {
    path: '',
    component: DashboardComponent
    , children: [
      {
        path: '',
        loadChildren: './home/home.module#HomeModule'
      },
      {

        path: 'rapport',
        loadChildren: '../rapport/rapport.module#RapportModule'
      },
      {
        path: 'admin',
        loadChildren: './admin/admin.module#AdminModule'
      }
    ]
  }];

@NgModule({
  imports: [
    RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

home.component.ts

import { Component, OnInit } from '@angular/core';
import { LayoutService } from '../shared/layout/services/layout.service';
import { UserConnected } from '../models/userConnected';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  constructor(public layoutService: LayoutService) { }
  userID: string;
  userExists : boolean = false;
  connectedUser = new UserConnected;
  ngOnInit() : void {
    this.connectedUser = this.layoutService.connectedUser;
    console.log("home connectedUser" + JSON.stringify(this.connectedUser));
    this.userID = this.connectedUser.uid;
    console.log("home userID" + this.userID);

    this.adminService.verifyUser(this.userID)
      .subscribe(
        (data) => {
          this.userExists = true;
        },
        (err) => {
          this.userExists = false;
        }
      );
  }

}

layoutService

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../../../environments/environment';
import { UserConnected } from 'src/app/models/userConnected';


@Injectable({
  providedIn: 'root'
})
export class LayoutService {
  
  connectedUser : UserConnected;

  constructor(private http:HttpClient) { }

   getConnectedUser(){
    return this.http.get<UserConnected>(environment.RAA_ROOT + '/connectedUser');
  }

}

Answer №1

connectUser within the LayoutService module seems to be the root cause of the issue you are facing.

connectedUser : UserConnected = new UserConnected();

This code snippet will ensure that you have the correct object type from the UserConnected class, preventing any errors during access. Keep on coding happily! :)

Answer №2

If you want to make changes, start by modifying the line in your HomeComponent like this:

this.connectedUser = this.layoutService.getConnectedUser()

Instead of using

this.connectedUser = this.layoutService.connectedUser;
, which will return undefined if not assigned in your layoutService.

Remember that http.get is asynchronous and returns an observable. You need to subscribe to it to use it in your component or utilize asyncPipe if you plan to use it in your template.

To proceed:

this.layoutService.getConnectedUser().subscribe((connectedUser) => { this.connectedUser = connectedUser; })

For further explanation, visit: https://angular.io/tutorial/toh-pt6

Answer №3

If you want to enhance the performance of your service, consider updating the implementation and implementing a more efficient caching system:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../../../environments/environment';
import { UserConnected } from 'src/app/models/userConnected';


@Injectable({
  providedIn: 'root'
})
export class LayoutService {
  
  private _cachedConnectedUser: UserConnected;

  constructor(private http:HttpClient) { }

   getConnectedUser(): Observable<UserConnected> {

    if (this._cachedConnectedUser ) {
      return of(this._cachedConnectedUser);
    }

    return this.http.get<UserConnected>(environment.RAA_ROOT + '/connectedUser')
     .map(response =>  {
       this._cachedConnectedUser = response.body;
       return this._cachedConnectedUser;
     });
  }    
}

Once implemented, you can simply call layoutService.getConnectedUser() to retrieve the object without managing additional local variables.

For further optimization of the caching mechanism, refer to this informative article: here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dynamically adjust the label position based on the button position

I am currently developing an interface that allows users to change the position of buttons and add a label text under the button. However, I am facing an issue where the label is not always centered below the button due to variations in the size and number ...

Chrome stack router outlet and the utilization of the Angular back button

I'm experiencing an issue with the back button on Chrome while using Angular 14. When I return to a previous page (URL), instead of deleting the current page components, it keeps adding more and more as I continue to press the back button (the deeper ...

Tips for managing a group of checkboxes in Angular 2 RC5

My task involves creating a form where users can edit their magazine subscriptions. Here is the code snippet I am working with: Component: export class OrderFormComponent { subscriptions = [ {id: 'weekly', display: 'Weekly new ...

I have encountered the same installation error with every Angular Masonry package I have tried to install on various applications

Every time I try to install one of the popular masonry packages for Angular, I encounter the same frustrating error. It's getting to the point where I feel like pulling my hair out. Unexpected token d in JSON at position 702 while parsing near ' ...

Encountering problem while upgrading Angular Material from version 13 to 14 - error TS2307: Module '@angular/material/core/common-behaviors/constructor' not found

While upgrading Angular and Angular Material from version 13.2.6 to 14.2.2, I encountered the following challenges: Error TS2307: Module '@angular/material/core/common-behaviors/constructor' or its type declarations cannot be found. Error TS2345 ...

Arrange the list by first names in the array using Ionic 3

What is the process for arranging a list by firstName from an array? This is my code in my.ts file: initializeItems(){ this.items = [ { avatar: '../../assets/imgs/profile1.jpg', firstName:'Sterlian', lastName:'Victorian ...

Select dropdown menu with dynamic search feature

I need assistance with creating an editable mat select dropdown that fetches data from an API as an array of objects. I want the dropdown to have a filter autocomplete feature where if a user types 'R', it should filter out options starting with ...

The functionality of the Request interface appears to be malfunctioning

Hey there, I'm currently working on building an API using Express and TypeScript. My goal is to extend the Request object to include a user property. I've done some research on Google and found several posts on StackOverflow that explain how to d ...

Issues installing dependencies in Angular using npm

Today I attempted to create a new project. I used the following command: ng new NAME --style=less However, when I ran this command in my cmder, it resulted in errors and warnings. To troubleshoot, I decided to uninstall Node.js along with the files in R ...

"Seeking advice on how to nest a service provider within another one in AngularJS 2. Any

I am faced with a product and cart list scenario. Below is the function I have created to iterate through the cart list and retrieve the specific product using its ID. getCartList(){ this.cart = CART; this.cart.forEach((cart: Cart) => ...

Setting base URLs for production and development in Angular 6: A step-by-step guide

As a beginner in Angular, I am looking for a way to set different base URLs for production and development environments. I aim to dynamically configure the base URL to avoid hard-coding it in the index.html file every time I switch between these two enviro ...

I am encountering an issue with retrieving JSON data within an ngrx effect

I've been struggling for the past two days trying to display local json data (posts) in my view (PostsComponent). I keep encountering this error message in the console: ERROR Error: Cannot find a differ supporting object '[object Object]' of ...

When validating storage content, session value appears as null

I have been working on developing an Ionic app that requires creating a session for user login. The goal is to store the user's name upon logging in, so it can be checked later if the user is still logged in. I have created a model class and a user cl ...

The exploration of child routes and modules

I'm currently working on a somewhat large project and I've decided to break it down into modules. However, I'm facing an issue with accessing the routes of admin.module.ts. In my app.module, I have imported the admin Module. imports: [ Br ...

What could be the root cause behind the error encountered while trying to authenticate a JWT?

I've been working on integrating a Google OAuth login feature. Once the user successfully logs in with their Google account, a JWT token is sent to this endpoint on my Express server, where it is then decoded using jsonwebtoken: app.post('/login/ ...

JavaScript Enigma: Instantiate 2 Date variables with identical values, yet they ultimately display distinct dates on the calendar

I need some help understanding something in my screenshot. Although both tmpStart and itemDate have been assigned the same numeric value, they display different calendar dates. start = 1490683782833 -> tmpStart = "Sun Mar 26 2017 16:51:55 GMT+ ...

Creating an array of custom objects in JavaScript.Initializing custom objects in an

Is there a proper way to prevent the error "Cannot read property 'length' of undefined" when initializing an array of custom objects in javascript? situation export class MyClass implements OnInit { myArray: MyObject[]; } example <div ...

Having trouble with your Ionic 2 Android release build getting stuck on a white screen post-splash screen?

Several weeks ago, I posted a question regarding this issue but unfortunately did not receive any response. So here I am posting again with a more specific problem. The Problem: 1.) I execute: $ ionic cordova build android --release --prod 2.) Then ...

Unlocking the accordion feature in Ionic 3 form: A step-by-step guide

I am currently working on a search form and want to incorporate it within an accordion so that users can simply click to expand the form. Below is the code snippet: TS. buildForm(): void { this.form = this.fb.group({ username: new FormControl(& ...

Block-level declarations are commonly used in TypeScript and Asp.net MVC 5

In my asp.net mvc5 project, I decided to incorporate TypeScript. I created an app.ts file and installed the nuget-package jquery.TypeScript.DefinitelyTyped. Here is a snippet of the app.ts code: /// <reference path="typings/jquery/jquery.d.ts"/> cl ...