How to Utilize an Array from Observable Object in Angular 2 with ngFor and Async Pipe

I am currently learning about the utilization of Observables in Angular 2. Here is a snippet of code from a service I am working with:

import {Injectable, EventEmitter, ViewChild} from '@angular/core';
import {Observable} from "rxjs/Observable";
import {Subject} from "rxjs/Subject";
import {BehaviorSubject} from "rxjs/Rx";
import {Availabilities} from './availabilities-interface'

@Injectable()
export class AppointmentChoiceStore {
    public _appointmentChoices: BehaviorSubject<Availabilities> = new BehaviorSubject<Availabilities>({"availabilities": [''], "length": 0})

    constructor() {}

    getAppointments() {
        return this.asObservable(this._appointmentChoices)
    }
    asObservable(subject: Subject<any>) {
        return new Observable(fn => subject.subscribe(fn));
    }
}

In this service, new values are pushed to the BehaviorSubject from another service like this:

that._appointmentChoiceStore._appointmentChoices.next(parseObject)

To display the data, I subscribe to it in the component using an observable:

import {Component, OnInit, AfterViewInit} from '@angular/core'
import {AppointmentChoiceStore} from '../shared/appointment-choice-service'
import {Observable} from 'rxjs/Observable'
import {Subject} from 'rxjs/Subject'
import {BehaviorSubject} from "rxjs/Rx";
import {Availabilities} from '../shared/availabilities-interface'


declare const moment: any

@Component({
    selector: 'my-appointment-choice',
    template: require('./appointmentchoice-template.html'),
    styles: [require('./appointmentchoice-style.css')],
    pipes: [CustomPipe]
})

export class AppointmentChoiceComponent implements OnInit, AfterViewInit {
    private _nextFourAppointments: Observable<string[]>
    
    constructor(private _appointmentChoiceStore: AppointmentChoiceStore) {
        this._appointmentChoiceStore.getAppointments().subscribe(function(value) {
            this._nextFourAppointments = value
        })
    }
}

When trying to display the data in the view, I encountered an error:

  <li *ngFor="#appointment of _nextFourAppointments.availabilities | async">
         <div class="text-left appointment-flex">{{appointment | date: 'EEE' | uppercase}}

Even though I defined the 'availabilities' property in the interface, the error message I received was:

browser_adapter.js:77 ORIGINAL EXCEPTION: TypeError: Cannot read property 'availabilties' of undefined

Answer №1

Let's take a look at an illustration

// handling data retrieval in the service
fetchData(){
    return Observable.interval(2200).map(i=> [{name: 'car 1'},{name: 'car 2'}])
}

// managing data in the controller
vehicles: Observable<Array<any>>
ngOnInit() {
    this.vehicles = this._dataService.fetchData();
}

// displaying data in the template
<div *ngFor='let data of vehicles | async'>
    {{data.name}}
</div>

Answer №2

If you happen to come across this message as well.

In my opinion, the accurate approach should be:

  <div *ngFor="let appointment of (_nextFourAppointments | async).availabilities;"> 
    <div>{{ appointment }}</div>
  </div>

Answer №3

Here is the solution you've been searching for:

<article *ngFor="let item of (data$ | async)?.items">
<h4 class="heading">{{item.title}}</h4>
<div class="description">{{item.description}}</div>
<footer>
    {{item.author}}
</footer>

Answer №4

If you find yourself without an array but are attempting to treat your observable as one even though it consists of a stream of objects, this approach will not yield the desired results by default. Below, I provide a solution assuming that your main concern is adding objects to the observable rather than deleting them.

When working with an observable that has a source of type BehaviorSubject, consider switching it to ReplaySubject. Then, in your component, subscribe to it in the following manner:

Component

this.items$ = this.dataService.items$.pipe(scan((acc, val) => [...acc, val], []));

HTML

<div class="item-list" *ngFor="let item of items$ | async">

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

Modifying tooltip format in React ApexChart from dots to commas

I am in the process of creating an app targeted towards German users, who traditionally use commas (20,00) instead of dots (20.00) for numbers. I am using react-apexcharts and struggling to figure out how to replace the dots with commas in both my chart an ...

Sending an HTTP POST request from Angular 4 to Java SpringMVC results in the issue of POST parameters not

Currently, I am developing a REST API using Java Maven Spring Boot and Spring MVC. I have encountered an issue where Angular POST request parameters are not being recognized by SpringMVC's @RequestParam. Below is the Angular code snippet; saveAsSit ...

Having trouble importing the Renderer2 component in Angular

Trying to include Renderer2 with the following import: import { Renderer2 } from '@angular/core'; Encountering an error: "Module 'project/node_modules/@angular/core/index' does not have an exported member 'Renderer2'. Puzz ...

Use leaflet.js in next js to conceal the remainder of the map surrounding the country

I'm currently facing an issue and would appreciate some assistance. My objective is to display only the map of Cameroon while hiding the other maps. I am utilizing Leaflet in conjunction with Next.js to showcase the map. I came across a helpful page R ...

Using useRef as a prop in React with TypeScript

I am currently experimenting with TypeScript and encountering an issue when trying to use useRef in a custom element specifically when passing it as a prop I have attempted the following: import React from "react"; export interface InputProps extends ...

Is it possible to eliminate the arrows from an input type while restricting the change to a specific component?

Is there a way to remove the arrows from my input field while still applying it only to the text fields within this component? <v-text-field class="inputPrice" type="number" v-model="$data._value" @change="send ...

Extending Enums in Typescript: A Comprehensive Guide

How can you work with a list of constants or Enum? Here is an example: enum MyList { A, B } enum MyList2 { C } function process<T>(input:MyList | T):void { } process<MyList2>(123) // The compiler does not recognize that 123 ...

Using NestJS to pass request and response parameters

I have a function in my services set up like this: ` @Injectable() export class AppService { getVerifyToken(req: Request, res: Response) { try { let accessToken = process.env.ACCES_TOKEN_FB; let token = req.query["hub.verify_t ...

Display an ellipsis (...) in ngx-datatable columns when the data exceeds the width

Seeking guidance on using ngx-datatable with Angular (). Currently facing an issue where text gets cut off when exceeding column width. Looking to implement ellipsis and show full details upon hovering over the truncated text or data. Any assistance ...

"Zone has been successfully loaded" - incorporating angular universal ssr

I am currently working on an Angular project and I am looking to implement server-side rendering. To achieve this, I decided to use Angular Universal. The browser module of my project was successfully built, but I encountered the following issue during the ...

Ways to induce scrolling in an overflow-y container

Is there a way to create an offset scroll within a div that contains a list generated by ngFor? I attempted the following on the div with overflow-y: @ViewChild('list') listRef: ElementRef; Then, upon clicking, I tried implementing this with s ...

Eliminate apostrophes in a string by using regular expressions

Can someone help me with this word What is The Answer? I need to eliminate the space and apostrophe '. To remove spaces, should I use this method: data.text.replace(/ +/g, ""). But how can I remove the apostrophe? ...

Troubleshooting Date Errors in Typescript with VueJS

Encountering a peculiar issue with Typescript while attempting to instantiate a new Date object. <template> <div> Testing Date</div> </template> <script lang="ts"> import Vue from "vue"; export default Vue.extend({ name: ...

Trouble arises when attempting to import React JSX project/modules from npm into an AngularJS TypeScript module

In the process of developing a proof-of-concept React framework/library, I aim to create a versatile solution that can be utilized in both React and AngularJS applications. To achieve this goal, I have initiated two separate projects: - sample-react-frame ...

What is the best way to resolve the "unknown" type using AxiosError?

I'm currently working on developing a customized hook for axios, but I've encountered the following error: Argument of type 'unknown' is not assignable to parameter of type 'SetStateAction<AxiosError<unknown, any> | unde ...

Encountering the error message "TypeError: Cannot access property 'Token' of undefined" while compiling fm.liveswitch

The fm.liveswitch JavaScript Software Development Kit (SDK) is designed for use with both clients and your own backend "app server". It functions smoothly in the frontend thanks to webpack and babel. However, the same import statement: import liveswitch fr ...

Retrieve a specific subdirectory from the bundle

I've developed a Typescript package with the following file structure: package.json src/ index.ts common/ index.ts sub/ index.ts My goal is to import certain modules from the package like this: import {...} from '<package>&ap ...

What is the best way to retrieve every single element stored in an Object?

On a particular page, users can view the detailed information of their loans. I have implemented a decorator that retrieves values using the get() method. Specifically, there is a section for partial repayments which displays individual payment items, as d ...

Ways to retrieve interface definition using a variable

I have an interface that organizes various states together export interface ScanFiltersStatePage1 { keywords: SensitiveInfoFileKeywordFilter categories: string[] classifications: string[] fileTypes: string[] infotypes: string[] regulations: str ...

Different Types of Props for Custom Input Components using React Hook Form

Struggling with creating a custom FormInput component using React Hook Form and defining types for it. When calling my component, I want to maintain autocompletion on the name property like this ... <FormInput control={control} name={"name"}& ...