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.