Pass service API data across initial components within Angular 6

I am currently working on creating a navigation bar that includes categories, as well as a home component that also relies on those same categories. My goal is to avoid making multiple API calls and instead utilize a single variable for the categories throughout my application. Below is my attempted solution:

Data Service

The Data Service fetches data from the specified API URL and returns a subscribable object.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  api_url: string = "https://apiurlhere";
  categories: Object;

  constructor(private http: HttpClient) { }

  getCategories(){
    return this.http.get(this.api_url+'/categorylisting/?z=1');
  }

  getZones(){
    return this.http.get(this.api_url+'/zones/');
  }

}

Navbar Component

The Navbar component utilizes the categories variable to display different options, with the subscription happening within this component.

import { Component, OnInit } from '@angular/core';
import { trigger, state, transition, animate, style } from '@angular/animations';
import { DataService } from '../data.service';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss'],
  animations: [
    trigger('slideInOut', [
      state('in', style({
        overflow: 'hidden',
        height: '*'
      })),
      state('out', style({
        overflow: 'hidden',
        height: '0px'
      })),
      transition('in => out', animate('400ms ease-in-out')),
      transition('out => in', animate('400ms ease-in-out'))
    ])
  ]
})
export class NavbarComponent implements OnInit {

  categories: Object;

  constructor(private data:DataService) { }

  ngOnInit() {
    this.data.getCategories().subscribe( data => {
      this.categories = data
      for(let category in this.categories){
        this.categories[category].productsOpen='out';
        for(let product in this.categories[category].product){
          this.categories[category].products[product].active = false;
        }
      }
      this.data.categories = this.categories;
    });
  }

  openProducts(index){
    this.categories[index].productsOpen = this.categories[index].productsOpen === 'out' ? 'in' : 'out';
  }

  setActiveProduct(index, productIndex){
    for(let category in this.categories){
      for(let product in this.categories[category].products){
        this.categories[category].products[product].active = false;
      }
    }
    this.categories[index].products[productIndex].active = true;
  }

}

Home Component

The Home component also requires access to the categories variable. However, I am facing issues accessing it here as it appears to be undefined even though it gets updated in the service.

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';

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

  categories: Object;

  constructor(private data:DataService) { }

  ngOnInit() {
    this.categories = this.data.categories;
  }

}

Is my approach correct? Coming from a background of React and Redux, where the render method re-renders upon changing the state, I am curious about how Angular handles changes in component variables. My main objective is to store my data globally so that I can reuse it without the need to make repeated API calls. Thank you.

Answer №1

To improve efficiency, consider caching the observable within your service:

export class DataManagement {

someData;

  api_endpoint: string = "https://apiurlhere";
  categories: Object;

  constructor(private http: HttpClient) { }

  fetchCategories(){
   if(!this.someData) {
     this.someData = this.http.get(this.api_endpoint+'/categorylisting/?z=1');
   }
     return this.someData;
  }
}

You may also explore angular's Http interceptors or utilize rxjs operator shareReplay for more advanced options.

Answer №2

If you're looking to fetch data from your API, one approach is to make the call in the constructor of a DataService class.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  api_url: string = "https://apiurlhere";
  categories: Object;

  constructor(private http: HttpClient) { 
    this.getCategories().subscribe(data => this.categories = data);
  }

  getCategories(){
    return this.http.get(this.api_url+'/categorylisting/?z=1');
  }

  getZones(){
    return this.http.get(this.api_url+'/zones/');
  }

}

Subsequently, you can retrieve the fetched categories in components like NavBar, following a similar pattern as seen in the Home component.

  ngOnInit() {
    this.categories = this.data.categories;
  }

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

The shop named 'someStore' is currently unavailable! Please ensure that it is being offered by a valid Provider

I'm having trouble setting up a new project using React, Typescript, and MobX. Despite having a relatively simple piece of code, I can't seem to get MobX to work properly. It keeps showing me this error message: Uncaught Error: MobX injector: S ...

The localhost of Mongod does not seem to be connecting properly with the 'npm start' command of my program

I'm currently developing a prototype program that handles account registrations, and my approach involves utilizing Node.JS to write JavaScript code that can be utilized on mobile devices. After downloading MongoDB and setting up the data/db director ...

The functionality of GetStaticProps with Typescript is only operational when defined as an arrow function, rather than a function

The documentation for GetStaticProps in NextJs explains it as a function declaration. When trying to add types to it, the following code snippet results: export async function getStaticProps(): GetStaticProps { const db = await openDB(); const fa ...

Retrieve the value of the object within the mysterious index loop in JavaScript

I have retrieved search results from the data, and each time the index of my search result varies. At one point, the result may appear in the 4th index, while at another time it might be in the 100th index. How can I retrieve the rank value from within t ...

Failure on the expect statement when comparing numbers in Jest..."The Jest magic number comparison is

I am currently conducting a test to verify that the magic number of a Buffer is in zip format. This involves extracting the first 4 bytes of the buffer into a string and comparing it with the magic number for zip, which is PK. const zipMagicNumber: str ...

Reactjs: Using setState to toggle checkbox selection

Currently dipping my toes into Reactjs, I decided to try my hand at a small project following the documentation. However, I've hit a roadblock. When the checkbox is checked, the state changes, but figuring out how to change it back when unchecked has ...

Ways to retrieve a list of identifiers from arrays at both initial and subsequent levels

I'm currently dealing with a JSON/JavaScript structure that looks like this: { "comments": [ { "id": 1, "content": "lorem ipsum", "answers": [] }, { "id" ...

Can you explain the significance of using the fat arrow syntax as a parameter in a function invocation?

I stumbled upon this code snippet on this website import {Http} from 'angular2/http' import {Injectable} from 'angular2/core' @Injectable() export class AddressBookService { http:Http; constructor(http:Http){ console.lo ...

Tips for recognizing a faulty CSS line in a WordPress site

Recently, I encountered an issue on my website, yildirimakademi, when using woocommerce to add a product to the shopping cart. While the shopping cart logo appears correctly on the right side of the navbar, I noticed that the image becomes distorted when ...

Feed JSON data into a jQuery function using JavaScript

A rudimentary Google Apps Script Web App has been created with the sole purpose of displaying JSON data in an HTML drop-down list. The JSON file is stored in Google Drive. Code inspiration taken from: http://jsfiddle.net/manoj_admlab/Mta5b/3/ However, we ...

Submitting form data in Angular is a straightforward process

I'm currently using the ng-flow library to upload images to my server. After a user drags and drops an image, I can successfully retrieve the HTML 5 file image in my controller. However, when trying to download it to the server along with other parame ...

Issue with gulp-uglifyjs arising from an empty return by gulp.src

Within a directory named app, I am iterating through an unknown number of folders to generate a folderName.min.js file for each one. Below is the Gulp script being used: var es = require('event-stream'); var uglify = require('gulp-uglifyjs ...

Enhancing unique designs

After searching for a background pattern, I stumbled upon this unique design. Currently, I have it as the backdrop for my website. The issue arises from the fact that this pattern doesn't seamlessly repeat. When I set it as the body background usin ...

Utilize JavaScript and PHP to dynamically modify the contents of an HTML file

After not receiving a satisfactory answer to my question yesterday, I decided to find a solution. However, I am now facing an issue with the new program and unsure of the mistake. The program involves retrieving the contents of announcement.html and displ ...

I'm wondering why my JWT token appears as null on the backend while it is not null on the frontend

I'm having trouble with a GET request to my mLab database. I included a JWT token in the request and verified it on both the client and server side. Strangely, it appears correctly on the client but as null on the server. Any assistance on this matter ...

Displaying a Vuetify stepper alert if required fields are left blank

I received assistance with developing this Vuetify stepper code, but I have one final inquiry. I have learned that there are specific rules that can be implemented to require certain blanks to be filled out. For example, in my code, if the blanks in step 3 ...

When attempting to render a React child, it is important to note that objects are not valid (found: [object Promise]). If your intention was to display a collection of children, it is advised

Instructions in "/pages/blog/index.js" : import BlogComponents from "../../components/Blog/blogComponents"; import { listBlogs } from "../../server/mongodb"; const index = async (props) => { console.log(props) return ( ...

Utilizing PHP, Javascript, and jQuery in mobile technology gadgets

Can anyone recommend mobile technology products that have been developed using PHP, Javascript, and jQuery? What are the newest mobile products available on the market that have been built using these languages? Do popular devices like iPhone, BlackBerry ...

Issue with JQuery click() not triggering on a specific div button

I am attempting to replicate a user's click on a website where I have no control over the code. The specific element I am trying to interact with is a div that functions as a button. <div role="button" class="c-T-S a-b a-b-B a-b-Ma oU v2" aria-dis ...

Having trouble retrieving accurate JSON data from an excel workbook

Currently, I am utilizing the npm module xlsx for the purpose of writing and reading JSON data. My goal is to take this JSON data and write it into an Excel file: { "name": "John", "class": 1, "address" : [ { "street": "12th Cross", "city": "London" }, { ...