How can state variables be accessed properly within a class while utilizing @ngrx/store?

I have a service that needs to make decisions based on the value of a variable stored in the AppState. Here is a simplified example of my service:

import { Injectable } from '@angular/core';
import { Store, select } from '@ngrx/store';

interface AppState {
  foo: boolean;
}

@Injectable()
export class FooProvider {

  private isFoo: boolean;

  constructor(private store: Store<AppState>) {
    // Check if it's foo
    store.pipe(select('foo')).subscribe((foo: boolean) => {
      this.isFoo = foo;
    });
  }

  isItFoo = (): string => this.isFoo ? "it's foo!" : 'nope, not foo';
}

Question: Is this the correct way to access and use a variable stored in the AppState within a class when using @ngrx/store?

In a Component, I could use the foo variable more simply with the async pipe like this:

import { Component } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { Observable } from 'rxjs';

interface AppState {
  foo: boolean;
}

@Component(
  selector: 'foo-component',
  template: `<p>{{ ( foo$ | async ) ? "it's foo!" : "nope, not foo" }}</p>`
)
export class FooComponent {

  private foo$: Observable<boolean>;

  constructor(private store: Store<AppState>) {
    this.foo$ = store.pipe(select('foo'));
  }
}

Is there a better or easier way to access state variables within a class?

Answer №1

In reference to an issue on GitHub, the feature of retrieving the current value was intentionally removed from ngrx due to misuse. Now, achieving this requires a workaround:

function getValue(o) {
  let value;
  o.take(1).subcribe(v => {
    value = v;
  });
  return value;
}

The main purpose of observables is to provide a continuous stream of data. Store values are mutable, and if a service that utilizes them is not reinstantiated, it will retain the old value. Therefore, it is expected that once there is a stream, it should be transformed and combined with other streams, only subscribed where it's consumed (often in a view using the async pipe).

In this specific scenario, the code snippet would look like this:

isItFoo$ = store.pipe(
  select('foo'),
  map((foo: boolean) => foo ? "it's foo!" : 'nope, not foo')
);

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

Schedule a daily Local Notification in Ionic 3 at a designated time

I have integrated the Ionic 3 local notification plugin into my project by running these commands: ionic cordova plugin add cordova-plugin-local-notification npm install --save @ionic-native/local-notifications All necessary dependencies have been added ...

The module './installers/setupEvents' could not be located within Electron-Winstaller

After encountering an error while attempting to package my Angular app on Windows 10, I'm looking for help in resolving the issue: https://i.stack.imgur.com/yByZf.jpg The command I am using is: "package-win": "electron-packager . qlocktwo-app --ove ...

Tips for utilizing the <img> onError attribute as a <div> tag

I'm looking to add a new URL with an onError function. '<div class="item" style="content:url(https://itemimage.jpg)" alt="No Product Image" ></div>' Here, I would like to include a default d ...

Reusing a lazy-loaded module across multiple applications

Currently, I am working on an enterprise Angular 2 application with numerous lazy loaded modules. A new project came up where I needed to reuse a module that was previously created for the main app. After researching online, the only solution I found was ...

Angular application does not prompt browser to save password

I have been developing an Angular application that kicks off with a login portal. The template I am currently utilizing for the login screen is as follows: login.html <form method="post" name="form" (ngSubmit)="f.form.valid && login()" #f= ...

Is there a way to showcase the JSON data retrieved from the server on page load in Angular 5?

At this moment, I have successfully set up a functionality on my HTML page where data is retrieved from a JSON object upon clicking a button. This is the method in my TS File: getData() { this.httpSvc.getConfig() .subscribe((data) => { ...

Exploring the Power of Angular 4's HttpClient Module

What differences are there between this code and the new HttpClientModule, where mapping from response.json() is no longer needed? //uses Http getLegalTerms(): Observable<legalterm[]> { return this._http.get(this._legalTermUrl) ...

Angular CLI simplifies the process of implementing internationalization (i18n) for Angular

After diving into the Angular documentation on i18n and using the ng tool xi18n, I am truly impressed by its capabilities. However, there is one part that has me stumped. According to the documentation, when internationalizing with the AOT compiler, you ...

Dealing with client-side exceptions in a Next.js 13 application's directory error handling

After carefully following the provided instructions on error handling in the Routing: Error Handling documentation, I have successfully implemented both error.tsx and global-error.tsx components in nested routes as well as the root app directory. However, ...

Angular Material 2 Progress Indicator Cover

Looking to implement a Progress Bar overlay during processing? I have the ability to calculate percentage complete and want to utilize a determinate progress bar for this task. Instead of a Spinner, I aim to use a dialog similar to what is demonstrated in ...

Opting In to Share Telemetry Data in Angular 8

Can someone help me understand how to enable the telemetry data sharing feature in Angular 8? I've done my research on the new features of Angular 8 and came across the option to opt-in for sharing usage data, but I'm unsure about where to find ...

The error property is not found in the type AxiosResponse<any, any> or { error: AxiosError<unknown, any>; }

As a beginner with typescript, I am encountering some issues with the following code snippet import axios, { AxiosResponse, AxiosError } from 'axios'; const get = async () => { const url = 'https://example.com'; const reques ...

How can I dynamically add a named property to a class during runtime and ensure that TypeScript recognizes it?

Within my coding project, I have implemented a decorator that alters a class by adding additional methods to it, specifically in the class A. However, when utilizing an instance of this class, the added methods do not show up in the autocomplete feature. A ...

What is the best way to reference a component variable property within its template without explicitly stating the variable name?

Suppose my component is managing an instance of the following class: class Person { firstName: string; lastName: string; age: number; } Is there a way to directly reference its properties in the template like this: <p>{{firstName}}</p> & ...

Utilize JQuery to choose the angular element

Can Angular tags be selected using JQuery? I am currently utilizing the ui-select Angular component, which is integrated into the HTML page as shown below: <ui-select ng-model="rec.currencyCode" on-select="ctrl.selectCurrencyCode(rec, $item)"> & ...

Creating a HTTP Post request in Angular with DocRaptor to receive the download URL in the response

Struggling to integrate Angular5 with DocRaptor has led me to hit a roadblock. Surprisingly, the DocRaptor website lacks any documentation on how to combine it with Angular, only offering a beginner's guide for 'other'. I've scoured thr ...

Controlling animation keyframes in Angular 2: a guide

Is there a way to manipulate CSS3/angular 2 animations using variables? Take a look at this modified code snippet from the official angular 2 animation docs: animations: [ trigger('flyInOut', [ state('in', style({position: &apos ...

How to retain the side menu icon in Ionic 2 even after navigating using navCtrl push

Whenever I navigate to a new page using navCtrl.push, the sidemenu icon (hamburger) disappears and is replaced by a back button instead of coexisting with it. What I am aiming for is to retain the sidemenu icon by positioning it on the right side of the i ...

How to efficiently upload multiple files simultaneously in Angular 10 and .NET Core 5 by utilizing a JSON object

I have a JSON object structured like this: Class->Students this is a basic representation of my TypeScript class export class Classroom { Id:number; Name:string; Students:Student[]=[]; } export class Student { Name:string; Age:number; Sex:string; Imag ...

What is the best way to loop through properties of a Typescript interface?

I am currently working with an interface called FilterData, which has the following structure: export interface FilterData { variables?: string[]; processDefinitionKey?: string; } When I make a request to the server, I receive an object named filterS ...