The firebase-generated observable is causing the notorious differ error as it is not iterable

Hey there, I'm encountering an issue that's preventing the route from rendering correctly. I initially thought that unwrapping an observable into an iterable using the async pipe would solve it, but this error indicates otherwise. Sometimes observables can be confusing. What do you think is causing the problem? Should I map this to an array before proceeding?

Error:

 MyOrdersComponent.html:5 ERROR Error: Cannot find a differ supporting object 'https://oshop-c71db.firebaseio.com/orders' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
        at NgForOf.ngOnChanges (common.js:2570)
        at checkAndUpdateDirectiveInline (core.js:12348)
        at checkAndUpdateNodeInline (core.js:13876)
        at checkAndUpdateNode (core.js:13819)
        at debugCheckAndUpdateNode (core.js:14712)
        at debugCheckDirectivesFn (core.js:14653)
        at Object.eval [as updateDirectives] (MyOrdersComponent.html:5)
        at Object.debugUpdateDirectives [as updateDirectives] (core.js:14638)
        at checkAndUpdateView (core.js:13785)
        at callViewAction (core.js:14136)

Template:

<h1>My Orders</h1>

    <p *ngFor="let order of this.orders$ | async">{{ order.datePlaced | date}}</p>

    <p class="card-text">You currently have 0 orders placed.</p>

    <table class="table table-hover table-striped ">
        <thead>
            <tr>
                <th>Order Placed</th>
                <th>Total</th>
                <th>Ship To</th>
                <th>Order Number</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let order of this.orders$ | async">
                <td></td>
                <td>{{ order.datePlaced | date}}</td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
        </tbody>
    </table>

Component:

import { AuthService } from './../auth.service';
    import { OrderService } from './../order.service';
    import { Component, OnInit } from '@angular/core';
    import 'rxjs/add/operator/switchMap';

@Component({
    selector: 'app-my-orders',
    templateUrl: './my-orders.component.html',
    styleUrls: ['./my-orders.component.css']
})
export class MyOrdersComponent {
    orders$;

    constructor(
        private authService: AuthService,
        private orderService: OrderService) {

        this.orders$ = authService.user$.map(u => orderService.getOrdersByUser(u.uid));
        // console.log(this.orders$);
    }
}

Order Service:

 import { AngularFireDatabase } from 'angularfire2/database-deprecated';
    import { Injectable } from '@angular/core';
    import { CartService } from './cart.service';

    @Injectable()
    export class OrderService {
        constructor(
            private db: AngularFireDatabase,
            private cartService: CartService
        ) { }

        async placeOrder(order) {
            const result = await this.db.list('/orders').push(order);
            this.cartService.clearCart();
            return result;
        }

        getOrders() {
            return this.db.list('/orders');
        }

        // getOrdersByUser(userId: string) {
        //     return this.db.list('/orders').$ref.orderByChild('userId');
        // }
        // getOrdersByUser(userId: string) {
        //     return this.db.list('/orders'.
        //         ref => ref.orderByChild('userId').equalTo(userId));
        // }
        getOrdersByUser(userId: string) {
            return this.db.list('/orders').$ref.orderByChild('userId').equalTo(userId);

        }

    }

Answer №1

If you are working with a function named getOrdersByUserId, it indicates that you will likely be dealing with an

Observable<Observable<T>>
, an
Observable<Promise<T>>
, or an Observable<T[]>.

In this case, using flatMap instead of map would be the appropriate approach.

Alternatively, consider utilizing concatMap or switchMap as mentioned in the comments.

Keep in mind that flatMap is essentially the same as

mergeMap</code (or vice versa), so you may opt to use either interchangeably. However, for consistency sake, it is recommended to stick to using just one - either <code>mergeMap
or flatMap throughout your project, as there are already plenty of terms referring to these operations.

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

Dynamically render a nested component, created within the parent component, using a directive

Can a nested component be dynamically rendered as a directive within the parent component? Instead of using the standard approach like this: <svg> <svg:g skick-back-drop-item /> </svg> where "skick-back-drop-item" is the s ...

Exploring the concept of inheritance and nested views within AngularJS

I've encountered a challenge while setting up nested views in AngularJS. Utilizing the ui-router library has been beneficial, but I'm facing issues with separate controllers for each view without proper inheritance between them. This results in h ...

Can you explain the significance of the @ symbol in TypeScript/Vue?

I've recently embarked on a new VueJS project and stumbled upon some unfamiliar syntax. I have highlighted the lines with comments below. file(example) : MyModule.vue const storeCompte = namespace("compte") // namespace is based on 'no ...

"Upon invoking the services provider in Ionic 2, an unexpected undefined value was

I encountered an issue while setting a value in the constructor of my page's constructor class. I made a call to the provider to fetch data. Within the service call, I was able to retrieve the data successfully. However, when I tried to access my vari ...

Storing information from JSON into an object

I am encountering an issue regarding transferring data from JSON to an object. Although this solution is functional, it is not entirely satisfactory. Take a look at the service. Is there an improved method for handling data conversion from this JSON to an ...

Different types of subscriptions for forkJoin observable

I am currently making two API requests with typed responses and combining them using the Observable.forkJoin method. My goal is to store each of the results in separate typed variables. var observableOrganization: Observable<Organization> = this.get ...

Put the item at the start of a viewable list

I have a critical Angular component that efficiently loads data into an Observable<Item[]> using a cleverly implemented BehaviorSubject<Item[]> triggered by the scroll position of a container reaching the bottom. The essential properties and t ...

What is the best way to reference class variables and methods within a callback function in Typescript?

While working on my Angular project with the Highcharts API, I encountered a situation where I needed to pass a state code to a class level method after drilling down to a specific map location. Below is the snippet of my current code: ngOnInit() { this. ...

Is it possible to initiate the onchange event in Angular programmatically using Typescript?

Despite changing the value of an input tag after returning a value from a dialog box (MatDialogRef), the associated change event fails to trigger. Attempts to use dispatchEvent have been made, but creating the event for triggering is not desired as per fo ...

Embrace the power of Angular2: Storing table information into

Custom table design Implement a TypeScript function to extract data from an array and populate it into a stylish table. ...

Enhance Angular Material Select with Tooltip on Ellipsis Directive

In the midst of my Angular 9 project journey, I encountered a directive designed to add a matTooltip if an element's text is truncated (ending in ellipsis due to overflow). Everything was running smoothly with this directive until I introduced a mate ...

The letter 'X' is not suitable for use as a JSX component because its return type 'Element[]' does not qualify as a valid JSX element

Currently, I am working on rendering two simple joke cards in TypeScript. The cards are displaying correctly in my browser, but I've encountered an error message that says: 'Jokes' cannot be used as a JSX component. Its return type 'Ele ...

In Laravel, a post request can pass a class with a property that is of a different class type

In my Laravel controller, I have the following function: public function save(Request $request, ClientOrderDTO $clientOrderDTO){ } The definition of the ClientOrderDTO used above is as follows: use App\DTO\ClientDTO; class ClientOrderD ...

Encountering an error with the iconv-lite package in TypeScript code

I recently added the "iconv-lite" package to my project, imported the module, and attempted to use the decode method. However, I encountered the following error: TypeError: Cannot read properties of undefined (reading 'decode') Interestingly, ...

Error encountered when implementing Angular Model Class within an array structure

In the current project, I have developed a class and am attempting to utilize the constructor format for certain content within the project. Here is my Angular class - import { Languages } from './temp-languages.enum'; export class Snippet { ...

How can Angular display an alert when no items are visible?

I want to display a message saying "Item doesn't exist" when the item is not found. Suppose this is my list: user 0 user 1 user 2 The following code displays the list above: <ng-container *ngFor="let user of users | async; let i = index"> ...

Handling routerLink exceptions in Angular 2, 4, and 5

In my app, I am working on catching routing exceptions. There are three ways in which a user can navigate: If the user types the address directly - this can be caught easily by using { path: '**', redirectTo: 'errorPage'} in the route ...

Angular 7 - Datatables - File Upload Feature

I'm trying to incorporate an "upload" button into my table: Below is my TS file with dtOption : ... order: [[3, 'desc']], dom: 'Blfrtip', stateSave: true, buttons: [ ...

Creating interactive forms - Incorporating dynamic checkbox options within the expansion panel element

Recently, I developed a basic movie list app with a checkbox list for genre filtering. Initially, I managed to achieve the desired functionality without using reactive forms. However, I am now exploring implementing the same functionality using reactive ...

Strategies for dealing with Observable inconsistencies in an Angular application

Encountering an error during the compilation of my Angular app: The error message states: Type 'Observable<Promise<void>>' is not compatible with type 'Observable<AuthResponseData>'. The issue lies in 'Promis ...