What is the most efficient way to extract the observable value property from an observable array?

I am working on a function called getLocationForEquipment, which is meant to take an array of observable locations, filter them based on a locationid parameter, and then return the location name for that specific location. I need to figure out how to utilize pipe, map, filter, and subscribe in order to retrieve this specific value.

import { LocationService } from 'src/app/services/location.service';
import { Equipment } from 'src/app/models/equipment';
import { Observable } from 'rxjs';
import { ActivatedRoute, Router } from '@angular/router';
import { Component, OnInit} from '@angular/core';
import { EquipmentService } from 'src/app/services/equipment.service';
import { RentService } from 'src/app/services/rent.service';
import { AccountService } from 'src/app/services/user.service';
import { Location } from 'src/app/models/location';
import {map} from 'rxjs/operators';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit {
    loading: boolean = false;
    submitted: boolean = false;
    openQrCode: boolean = false;
    enterPinCode: boolean = false;
    QrCode!: string;
  equipments: Observable<Equipment[]>
  locations!: Observable<Location[]>

    constructor(
    public locationService: LocationService,
        public accountService: AccountService,
    public equipmentService: EquipmentService,
    public rentService: RentService,
  ) {
    this.equipments = equipmentService.getAllEquipment(this.accountService.user.organizationid)
    this.locations = locationService.getAllLocations(this.accountService.user.organizationid)
  }

  ngOnInit() {
  }

  getLocationForEquipment(equipid: number) {
    this.locations.pipe (
      map(items => {      
        items.filter(item => item.id === equipid)
      }
  ))}

  onOpenQrScanner() {
    this.openQrCode = true;
  }

  scanSuccessHandler(scanValue: string) {
    console.log(scanValue)
    this.enterPinCode = true;
    this.QrCode = scanValue;
    console.log(scanValue)
    return this.scanSuccessHandler
  }

  scanErrorHandler(scanError: any) {
    console.log(scanError)
  }


}

HTML:

<ion-item-group>
    <ion-card *ngFor="let equipment of equipments | async">
      <ion-card-title class="class-title">{{getLocationForEquipment(equipment.locationid)}}</ion-card-title>
      <ion-card-subtitle class="class-subtitle">{{equipment.description}}</ion-card-subtitle>
    </ion-card>
  </ion-item-group>
export class Location {
  id!: number;
  organizationid!: number;
  name!: string;
  description!: string;
  active!: boolean;
}

Answer №1

It seems like you may need multiple ion-cards for each piece of equipment.

To start, consider renaming your observables to something like

equipments$ and locations$. This makes it easier to distinguish Observables from actual values (Learn more about this naming convention here: https://angular.io/guide/rx-library#naming-conventions-for-observables)

Next, make a change to your get Location function:

  getLocationForEquipment(equipid: number, locations: Location[]): Location {
    return locations.find(item => item.id === equipid);
  }

I switched from filter to find because you are looking for only one value. I also included a return type for clarity on the output. Additionally, the new parameter 'locations' represents the current received locations.

Then update your HTML code to:

<ion-item-group 
    *ngIf="{
      equipments: equipments$ | async
      locations: locations$ | async
    } as observables"
>
    <ion-card *ngFor="let equipment of (observables.equipments || [])">
      <ion-card-title class="class-title" *ngIf="observables.locations">{{getLocationForEquipment(equipment.locationid, observables.locations)?.name}} </ion-card-title>
      <ion-card-subtitle class="class-subtitle">{{equipment.description}}</ion-card-subtitle>
    </ion-card>
  </ion-item-group>

Since your observable contains array values, you must iterate over the returned value of the observable. To extract the value from the observable, I typically use *ngIf to define a variable and display nothing until the observable is triggered. In this scenario, we require the values from both observables, so I created a temporary object holding these values. Then utilized *ngFor to loop through the equipment array. Lastly, the function getLocationForEquipment is called with the current locationId and all available locations.

As I am unsure of the structure of a Location object, I simply used the arbitrary 'name' field to demonstrate how to display attributes.

p.s. Let me know if this code functions correctly, or if any errors occur since I did not actually run this code. Just implemented it in the browser lol

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

An issue has occurred in my deeply nested reactive form where I am unable to read the properties of null, specifically the 'controls' property

I have encountered an issue with a deeply nested form that communicates with a REST endpoint upon submission. While the first two levels of the form are functioning properly, I am facing numerous challenges when trying to work with the third level. One par ...

Angular 2: A guide to dynamically adding and updating meta tags through a component, similar to the title service functionality

As someone who is just beginning to explore Angular 2, I find myself in need of setting up meta tags such as og: description and others directly from a component. I am unsure of how to dynamically update these meta tags or add new ones to the index.html fr ...

Encountered Typescript issue when utilizing typed forms in Angular

Below is the interface I am working with: export interface ILoginDto { email: string; password: string; } Here is a snippet of the relevant code from the component: import { FormBuilder, FormGroup, Validators } from '@angular/forms'; export ...

TypeScript observable variable not defined

Recently, I encountered an issue and made a change to resolve it. However, I am unsure if it is the correct approach... In my project, I have defined an interface: export interface ContextEnvironment { language: string; pingUrl: string; sessionFini ...

Tips on sending a list via @Input using Angular5

I was seeking guidance on how to pass a list through an input. In my parent component, I have the following: list: Hero[] = [{Id: 2, Name: "Sll"}, {Id: 3, Name: "Sldsadasd"}] and in the HTML: <app-add-hero list="{{list}}" hero={{hero}}></app-ad ...

Comparing Redux and MVC models in software architecture

A new project is on the horizon, and the Product Owner has suggested using Redux for state management. However, I am hesitant to embrace this suggestion as I fail to see the advantages compared to a model-based approach. For instance, instead of utilizin ...

Can parameters with identical union types in a function signature be streamlined to contain only the exact same subtypes using generic types?

// defining a type Combinable with string or number as possible values type Combinable = string | number; // function to check if parameter is a string function isString(param: unknown): param is string { return typeof param === "string"; } /** * Func ...

Modifying the color of the error icon in Quasar's q-input component: a step-by-step guide

https://i.stack.imgur.com/4MN60.png Is it possible to modify the color of the '!' icon? ...

Issue with Angular 8+: *ngFor loop not rendering data on the HTML page despite successful data retrieval in console.log()

I am attempting to showcase a list of tuitions in a table with a separate component for each result in the list using *ngFor. However, the HTML is not rendering it properly. console.log() accurately prints the data (list of tuitions) : View console log da ...

Tips for managing and identifying canceled requests in an Angular HTTP interceptor

Having trouble handling cancelled requests in my http interceptor. Despite trying various methods from SO, I can't seem to catch it. Here is an example of how my interceptor looks: public intercept(req: HttpRequest<any>, next: HttpHandler) { ...

Creating and sharing a project in Typescript

My typescript project tends to have its code scattered across multiple files during development. Is there a recommended method for packaging this project into a single js and d.ts file for distribution? ...

latest version of PrimeNG dropdown is 16.2

I am inquiring about how to implement virtual scrolling in a dropdown menu and connect the virtual scroll with an API backend. Specifically, I would like to know how to trigger an API call when the user reaches the end of the scroll, incrementing the page ...

What could be the reason for the webpack:// not showing up in Chrome after running ng build?

Greetings, I'm relatively new to Angular and have noticed a difference between using ng serve and ng build. When I use ng serve, I can see webpack:// in the Chrome debugger which allows me to navigate my TypeScript files for debugging. However, when I ...

Is there a way to trigger a function upon the loading of a template in Angular 2?

I'm a newcomer to angular2 and I need to trigger a function when a template loads or initializes. I have experience with achieving this in angular1.x, but I'm struggling to figure out how to do it in angular-2. Here's how I approached it in ...

Check to see whether the coordinates fall inside the specified bounding box

I am faced with the task of creating a function that can determine whether a given coordinate c lies within the boundaries of coordinates a and b. All variables in this scenario are of type: type Coordinate = { lat: number; lon: number; }; Initially ...

Choose a date range from the date picker

I am currently attempting to combine two dates using a rangepicker. Below is the command used to select the date: Cypress.Commands.add('setDatePickerDate', (selector, date) => { const monthsShort = [ 'janv.', 'févr.& ...

A solution for resolving the RuntimeException in genuitec's TypeScript Editor for Eclipse Oxygen

After setting up a fresh Eclipse Oxygen and installing the Angular IDE from Genuitec, I encountered an issue on the second day when I opened a project and accessed a *.ts File. The error message displayed was: java.lang.RuntimeException: java.lang.Illegal ...

Maintaining the essence of generics while encapsulating functions

I am currently facing a challenge in defining a function that can wrap any other function while maintaining the parameter types and return type. I have managed to achieve this when the function does not use generics, but I am encountering difficulties wi ...

Unable to store the outcomes from [ngbTypeahead] in [resultTemplate]

I'm trying to integrate ngbTypeahead into my HTML using the code snippet below <ng-template #rt let-r="result" let-t="term"> <ngb-highlight [result]="r.FirstName" [term]="t"></ngb-highlight> </ng-template> <input name ...

Is it necessary for TrackBy to be a function in Angular 2, or can it be undefined?

Struggling with an error while developing a demo app in Angular 2. The error message reads: core.umd.js:3491 EXCEPTION: Uncaught (in promise): Error: Error in security.component.html:35:72 caused by: trackBy must be a function, but received undefined. Err ...