Connect store variables to components using Angular's ngrx

I am attempting to link the location variable in my component to another variable in the store using a selector with ngrx v13 in Angular. However, when I include the variable with the property in the HTML, I encounter an error:

Error message: Property 'name' does not exist on type 'Observable'

Here is my code:

app.selector.ts

import { createSelector } from "@ngrx/store";

export const CurrentLocationSelector = (state: AppState) => state.currentLocation;
export const getCurrentLocation = createSelector(
    CurrentLocationSelector,
    (currentLocation: any) => {
      return [...new Set(currentLocation)];
    }
);

This is my AppState:

interface AppState{
    darktheme: boolean;
    temperatureUnit: string;
    currentLocation: any; // object representing the current location
    locationAutoComplete: any[]; // array containing autocomplete results
    locationCurrentWeather: CurrentItem | null;
    Forecast5Days: ForecastItem[];
    Favorites: FavoriteItem[];
    loading: boolean;
    getData: boolean;
}

In my component, I have written: current-weather.component.html

         <div class="left">
             <span class="locationName">{{location$.name}}</span>
             <span class="date">{{currentFullDate}}</span>
             <div class="weatherDescription">
                 <img [src]="imageCurrentWeather" class="weatherIcon">
                 <div class="weatherText">{{CurrentWeather.WeatherText}}</div>
             </div>
             <h1 [innerHTML]="CurrentWeather.Temperature + ' ' + currentUnit"></h1>
         </div>

In my current-weather.component.ts, I have the following code:

  location$ = this.store.pipe(select(CurrentLocationSelector))

Answer №1

The issue at hand is that you have designated your variable location$ as an observable. This implies that it doesn't represent a single object carrying your data, but rather a stream of multiple values that could potentially hold your data at different points in time.

Therefore, to access the value of your object at a specific moment - typically the current moment - you must use .subscribe() to listen for incoming observables, and .select to tune into your desired selector containing the data you require, like so:

Within your current-weather.component.ts file:

let $location;
this.store.select(CurrentLocationSelector).subscribe(location => {
  $location = location; // set a debug break point here to observe the updated value
});

Answer №2

Utilize the async pipe with the observable location$.

<span class="locationName">{{(location$ | async).name}}</span>

current-weather.component.html

     <div class="left">
         <span class="locationName">{{(location$ | async).name}}/span>
         <span class="date">{{currentFullDate}}</span>
         <div class="weatherDescription">
             <img [src]="imageCurrentWeather" class="weatherIcon">
             <div class="weatherText">{{CurrentWeather.WeatherText}}</div>
         </div>
         <h1 [innerHTML]="CurrentWeather.Temperature + ' ' + currentUnit"></h1>
     </div>

Resource for using async pipe

Answer №3

You have switched the order of .pipe and select:

Give this a try:

this.location$ = this.store.select(CurrentLocationSelector).pipe(map((location)=> {return location;}))

If the issue persists, it may be due to the selector itself. Consider using createFeatureSelector:

import { createFeatureSelector, createSelector } from '@ngrx/store';
import { AppState } from './app.state';
export const APP_STATE_NAME = 'app';

const getAppState =
  createFeatureSelector<AppState>(APP_STATE_NAME);

export const getLocation = createSelector(getAppState, (state) => {
  return state.currentLocation;
});

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

Check to see if the upcoming birthday falls within the next week

I'm trying to decide whether or not to display a tag for an upcoming birthday using this boolean logic, but I'm a bit confused. const birthDayDate = new Date('1997-09-20'); const now = new Date(); const today = new Date(now.getFullYear( ...

Update the TemplateUrl according to the URL Parameters (GET)

I've created a basic Angular code snippet (test.component.ts) that retrieves a variable from GET parameters: import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ select ...

Deconstructing Angular 2 Custom Pipes

As I delve deeper into learning Angular 2, my recent endeavor involves creating a custom pipe to filter results in my gallery by category. Unfortunately, the resources I've been referring to lack detailed explanations on how custom pipes actually work ...

Update a particular form field value prior to submission

Currently, I am working on a User registration page that includes the functionality for users to upload their own avatar picture. My approach involves uploading the picture, then calling a function on change to convert the picture into a UInt8Array before ...

Angular - Dropdown menu fails to display options

I encountered an issue with the JSON response from my Angular-12 API endpoint: { "message": "vehicle Model Detail.", "error": false, "code": 200, "results": { "vehiclemakes": [{ ...

Imitating elegant angular input styles

Just before launch, the higher-ups have decided that they prefer a modern aesthetic for input controls - underlines rather than boxes, with labels that slide out of the way when the input is in focus. Check out the effect on this page: https://material.an ...

Tips for creating a stylish, blurred, and centered box for a login form on a full-size background that is also responsive

I attempted to create a login form on an HTML page using Angular, featuring a full-size background image that is centered. The form itself is contained within a div with a blurred background, also centered both horizontally and vertically within the browse ...

Using Angular 8, you can create a reactive form that includes a custom ng-select component which has

My custom angular reactive form includes a ng-select component along with other elements. I have implemented the following code to validate the form: private validateCustForm() { this.validation.touchFormControls(this.appointmentForm); if (this.ap ...

information received from the socket is not displaying on the screen

I am receiving data from socket io but it is not displaying in the view. Here is the function in my TypeScript file: socketIO.on('hello', (data) => { console.log('data', data); this.mydata= data; ...

Is there a way to use a single url in Angular for all routing purposes

My app's main page is accessed through this url: http://localhost:4200/ Every time the user clicks on a next button, a new screen is loaded with a different url pattern, examples of which are shown below: http://localhost:4200/screen/static/text/1/0 ...

How can I send a parameter to a function and retrieve it upon clicking in Angular?

app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = & ...

Dynamic Dropdown Options in Angular 6 HTML Input Field

Looking to create an interactive HTML5 input field that guides the user with their input. Consider a scenario where the user is required to follow a specific grammar while entering text: rule: <expression> {<op><expression>} expression: ...

When considering Angular directives, which is more suitable for this scenario: structural or attribute?

In the process of developing an Angular 5 directive, I aim to incorporate various host views (generated from a component) into the viewContainer. However, I find myself at a crossroads as to whether I should opt for an attribute directive or a structural ...

Is it possible to categorize a JSON object based on its properties and then count the occurrences of each property within

I have an array of objects containing booking information and I need to calculate the count of each booking item in every object. const arr = [ { "ID" : 1, "Name":"ABC", "Bookings":[ { & ...

AbstractControl is missing the 'controls' property in Angular4

Many blogs have discussed this error, but none specifically for angular4. I am dynamically adding and removing controls on the form. Add controls to the form during initialization ngOnInit() { this.lienHolder = this._fb.group({ ...

How can one effectively monitor the advancement of a file transfer operation?

Looking at integrating a Spring Boot REST API with an Angular Frontend, I am interested in monitoring file upload/download progress. I recently came across an informative article that dives into the implementation details of this feature. The approach see ...

How to easily scroll to the top of the previous page in Angular 8

In my Angular 8 application, there are buttons that are meant to take the user back to the previous page when clicked. While the functionality works as expected, I am facing an issue where the page does not automatically scroll to the top upon navigating ...

Angular 7 navigation successfully updates the URL, but fails to load the corresponding component

Despite exhausting all other options, I am still facing a persistent issue: when trying to navigate to a different component, the URL changes but the destination component fails to load. Explanation: Upon entering the App, the user is directed to either ...

How to prevent users from accessing the app through standard web browsers in an Express/Electron application

My setup involves an express server that serves my angular front end at http://localhost:9000 Utilizing electron as a desktop client is part of my project. I am aiming to restrict users from accessing the application through any browser except electron. ...

The Angular HTTP service dependency injection does not provide a return value

I am currently facing an issue with calling a service named MachineLearningService from my helper function. This service is supposed to receive arguments and return a response from an API. Strangely, after adding the HTTP dependency in my constructor, I am ...