Refreshing Components upon updates to session storage - Angular

Currently, I am in the process of developing a build-a-burger website using Angular. The ingredients and inventory need to be updated dynamically based on the selected location. Users can choose the location from a dropdown menu in the navigation bar.

The issue I'm facing is that every time I update the location in session storage, I have to manually refresh the page for the new inventory to load. Is there a way to make it automatically render the updated inventory when the location changes in session storage?

Here is my app.component.html:

  <select id="locations" appAuthOnly [isVerified]="isVerified" [(ngModel)]="selectedLocation"  (change)="onLocationChange()">
<option value="Mystic Falls">Mystic Falls</option>
<option value="Riverdale">Riverdale</option>
<option value="Sunnydale">Sunnydale</option>

This is the app.component.ts:

  ngOnInit() {
this.isVerified = localStorage.getItem('token') ? true : false;
console.log(this.selectedLocation);
this.selectedLocation = sessionStorage.getItem('selectedLocation') || 'Mystic Falls';
  }

  onLocationChange() {
    sessionStorage.setItem('selectedLocation', this.selectedLocation);
  }

UPDATED:

onLocationChange() {
  sessionStorage.setItem('selectedLocation', this.selectedLocation);
  this.ingrediantService.getAllItems();
}
}

My ingrediants.service.ts:

  selectedLocation: string = sessionStorage.getItem('selectedLocation') ?? '';

  getAllItems(): Observable<Ingrediant[]> {
    const selectedLocation = sessionStorage.getItem('selectedLocation') ?? '';
    return this.http.get<Ingrediant[]>(this.url).pipe(
      map(ingredients => ingredients.filter(ingredient => ingredient.location === selectedLocation))     
    );

  }

And lastly - inventory-ingrediants.component.ts:

ngOnInit() {
    // Retrieve the ingredients
    this.ingrediantService.getAllItems().subscribe((data) => {
        console.log(data);
        this.breadIngrediants = data.filter(ingredient => ingredient.category === 'Bread');
        this.pattyIngrediants = data.filter(ingredient => ingredient.category === 'Patty');
        this.cheeseIngrediants = data.filter(ingredient => ingredient.category === 'Cheese');
        this.garnishIngrediants = data.filter(ingredient => ingredient.category === 'Garnish');
        this.sauceIngrediants = data.filter(ingredient => ingredient.category === 'Sauce');
    });

    this.carousel = this.elementRef.nativeElement.querySelector('.carousel-container');
    this.arrowLeft = this.elementRef.nativeElement.querySelector('.arrow-left');
    this.arrowRight = this.elementRef.nativeElement.querySelector('.arrow-right');

    // Subscribe to the watchSessionStorage method to listen for changes to the session storage
 
        
        };

Answer №1

Observables are a powerful tool for reacting to changes in your application, but it's important to properly declare the types of changes that will occur and identify who will trigger these changes.

If you have multiple components listening for changes and various events responsible for triggering those changes, using a BehaviorSubject is often recommended. This extends the functionality of observables and allows you to store a shared observable in a service such as ingredients.service, like this:

ingredients.service.ts:

items$: new BehaviorSubject<Ingredient[]>([]);

 getAllItems(): void {
     const selectedLocation = sessionStorage.getItem('selectedLocation') ?? '';

    this.http.get<Ingredient[]>(this.url).pipe(
        map(ingredients => ingredients.filter(
            ingredient => ingredient.location === selectedLocation
        )
    )).subscribe((res) => this.items$.next(res));
}

In other parts of your code, you can simply refer to items$ when needed, like so:

some-file.html:

<div *ngFor="let item of (items$ | async)">{{item.name}}</div> 

or in some-file.ts:

method() {
    this.ingredientsService.items$.subscribe((items) => {
        console.log(items);
    });
}

To initialize the data on app start, make the first call to retrieve ingredients in your app.component.ts:

app.component.ts:

ngOnInit() {
    //... your code here

    this.ingredientsService.getAllItems();
}

When you need to update the items data, simply call:

this.ingredientsService.getAllItems();

Your subscribers will be automatically updated with the latest data.

Answer №2

When the selection is changed, I am unable to see the new call for the update. Please refer to the code below, you are free to modify the onLocationChange() function as needed. I recommend making a new request each time the select input changes.

ngOnInit() {

    // FIRST CALL
    this.getIngredients()

    this.carousel = this.elementRef.nativeElement.querySelector('.carousel-container');
    this.arrowLeft = this.elementRef.nativeElement.querySelector('.arrow-left');
    this.arrowRight = this.elementRef.nativeElement.querySelector('.arrow-right');


}
   
getIngredients() {
   this.ingrediantService.getAllItems().subscribe((data) => {
        console.log(data);
        this.breadIngrediants = data.filter(ingredient => ingredient.category === 'Bread');
        this.pattyIngrediants = data.filter(ingredient => ingredient.category === 'Patty');
        this.cheeseIngrediants = data.filter(ingredient => ingredient.category === 'Cheese');
        this.garnishIngrediants = data.filter(ingredient => ingredient.category === 'Garnish');
        this.sauceIngrediants = data.filter(ingredient => ingredient.category === 'Sauce');
    });
}

onLocationChange() {
     sessionStorage.setItem('selectedLocation', this.selectedLocation);
     // EACH TIME SELECT CHANGE NEW CALL IS EXECUTED
     this.getIngredients();

}

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

NPM is currently experiencing difficulties installing or uninstalling packages

I'm having trouble installing or uninstalling any npm package because of an error that says "Cannot find module 'emoji-regex'." Does anyone know what might be causing this issue? Here are my configurations. I also tried running "npm install ...

Having Trouble Setting Default Value in React Typescript MUI Autocomplete

I am encountering an issue with my React and Typescript code using MUI with the use of hook form. The problem arises when trying to set a default value for an Autocomplete field, resulting in the following error message: I am seeking assistance in resolvi ...

Attempting to transpile JavaScript or TypeScript files for compatibility within a Node environment

Our node environment requires that our JavaScript files undergo Babel processing. Figuring out how to handle this has been manageable. The challenge lies in the fact that we have a mix of file types including .js, .jsx, .ts, and .tsx, which is not subject ...

Capturing user input with Angular Material forms in HTML

In the process of working on a project in Angular, I am utilizing the Angular Material component library. As part of this project, I am creating a form with multiple fields. Everything is functioning properly, however, the layout appears slightly off: ht ...

Moving the starting directory of a NodeJS application on Azure

My NodeJS app on Azure was initially written in Javascript with the app.js file located in the root directory. This file was automatically detected during deployment via Git. Recently, I converted the app to Typescript and now have a build directory, with ...

Navigating and Organizing in Ionic Service Factory

Apologies for the beginner question. I am looking to incorporate filtering and sorting by name on my webpage. However, I have encountered two issues after attempting to implement this functionality using a factory in services.js: When typing a search ter ...

Searching for MongoDB / Mongoose - Using FindOneById with specific conditions to match the value of an array inside an object nestled within another array

Although the title of this question may be lengthy, I trust you grasp my meaning with an example. This represents my MongoDB structure: { "_id":{ "$oid":"62408e6bec1c0f7a413c093a" }, "visitors":[ { "firstSource":"12 ...

What is the process for overriding the module declaration for `*.svg` in Next.js?

The recent modification in Next.js (v11.0.x) has introduced new type definitions: For next-env.d.ts (regenerated at every build and not modifiable): /// <reference types="next" /> /// <reference types="next/types/global" /> ...

Unable to retrieve information from service using Angular 1.6 and TypeScript

I'm having an issue retrieving data from a Service in my Controller. Here is the code for my Service file: import {IHttpService} from 'Angular'; export class MyService { public static $inject = ['$http']; constructor(private $htt ...

Obtain a collection of custom objects through an HTTP GET request to be utilized in an Angular 2 application

I am currently grappling with the task of efficiently retrieving a list of custom objects and displaying their contents using an HTML file. Here is a simplified version of the HTTP GET method that I am working with: [HttpGet("/atr/testing")] public List& ...

Having issues with TypeScript custom commands in Cypress?

Update: https://github.com/cypress-io/cypress/issues/1065#issuecomment-351769720 Removing an import from my commands.ts fixed it. Thanks In the process of transitioning my cypress project to use TypeScript, I am following the guidelines provided at https: ...

Exploring Angular 2: Unveiling the secrets of lifecycle hooks in lazy loaded

Currently, I'm working on an application that involves lazy loaded Angular modules. I have a straightforward inquiry: Is there a way to detect an event once a module is loaded? For instance, similar to the OnInit lifecycle hook for components. I fo ...

What steps do I need to take to ensure that the external API proxy for Angular 8 functions properly, without automatically defaulting to

In my current project, I'm attempting to set up a development Angular application to streamline the process of writing and testing services for our main NativeScript app in production. One of the challenges I've encountered is dealing with the C ...

Failure to invoke Facebook login callback function

I am currently working on implementing the FB api for login in an angularjs app, using the angular-facebook library. The functionality works fine, but I have encountered a problem where the callback is not triggered after the user authorizes the app. Thi ...

Encountered error: Unable to locate module - Path 'fs' not found in '/home/bassam/throwaway/chakra-ts/node_modules/dotenv/lib' within newly generated Chakra application

Started by creating the app using yarn create react-app chakra-ts --template @chakra-ui/typescript. Next, added dotenv with yarn add dotenv Inserted the following code block into App.tsx as per the instructions from dotenv documentation: import * as dote ...

Tips for validating a text input field depending on the selected value in a dropdown menu using AngularJS

When a user selects from the dropdown menu, they can choose between Number and Decimalnumber. If the user selects Number, the text box should only allow whole numbers (e.g. 22, 33, 444, 345436). The user should not be able to enter decimal values like 22 ...

Terser is causing ng build --prod to fail

When I run ng build --prod on my Angular 7 application (which includes a C# app on the BE), I encounter the following error: ERROR in scripts.db02b1660e4ae815041b.js from Terser Unexpected token: keyword (var) [scripts.db02b1660e4ae815041b.js:5,8] It see ...

Exploring Angular's filtering capabilities and the ngModelChange binding

Currently, I am in the process of working on a project for a hotel. Specifically, I have been focusing on developing a reservation screen where users can input information such as the hotel name, region name, check-in and check-out dates, along with the nu ...

Tips for managing both DOM manipulation and state changes at the same time in AngularJS

<div my-custom-directive> <button id="myButton" ng-click="handleClick(mymodel.id)"><button> </div> app.controller('myCtrl', function($scope) { $scope.handleClick = function(id) { //Perform state change here without ...

Ways to expand the DOM Node type to include additional attributes

I've been diving into typescript and transitioning my current code to use it. In the code snippet below, my goal is: Retrieve selection Get anchorNode from selection -> which is of type 'Node' If anchorNode has attributes, retrieve attr ...