The service that offers an Observable on a specific subject is not receiving any notifications

The EventSpinner component is designed to subscribe to icons provided by the EventsService.

@Component({
    selector: 'event-spinner',
    template: `
<div class="col-xs-5">
    Test <i class="fa fa-2x" [ngClass]="{'fa-check': icon == 'ok', 'fa-spin': icon == 'loading', 'fa-spinner': icon == 'loading', 'fa-times': icon == 'error'}" id="spin"></i>
</div>
  `
})
export class EventSpinner implements OnInit {
    icon: string;

    constructor(public eventsService: EventsService) {
    }

    ngOnInit(): void {
        this.eventsService.icons.subscribe((icon) => {
            let old = this.icon;
            this.icon = icon;
            console.log("this.icon = " + this.icon + " (was " + old + ")");
        });
    }

}

When a web service request using @angular/http.get state changes ("loading"/"ok"/"error"), icons.next is called. However, there seems to be an issue where the class of the i tag doesn't get updated. Any ideas on how to resolve this?

EventsService.ts

@Injectable()
export class EventsService {
    icons: Subject<string> = new Subject<string>();

    constructor(public http: Http) {
    }

    subscribe(): Observable<Event[]> {
        let url = (<any>window).__ext.API_URL + 'event/view';
        let obs;
        return Observable
            .create((o) => {
                obs = o;
                obs.next();
            })
            .flatMap(() => {
                this.icons.next("loading");
                console.log("executing request");
                return this.http.get(url)
            })
            .retryWhen(error => {
                this.icons.next("error");
                return error.delay(3000);
            })
            .map((response: Response) => {
                this.icons.next("ok");
                console.log("response received");
                setTimeout(() => {
                    console.log("pushing next");
                    obs.next();
                }, 1000);
                return (<any>response.json()).map(item => {
                    return item;
                });
            });
    }
}

Answer №1

Perhaps the root cause lies in how EventService is implemented or there could be a potential issue with ngClass. One possible workaround is to manually trigger change detection as shown below:

export class EventSpinner implements OnInit {
    icon: string;

    constructor(public eventsService: EventsService, private cdRef:ChangeDetectorRef) {
    }

    ngOnInit(): void {
        this.eventsService.icons.subscribe((icon) => {
            let old = this.icon;
            this.icon = icon;
            console.log("this.icon = " + this.icon + " (was " + old + ")");
            this.cdRef.detectChanges();
        });
    }
}

Answer №2

After implementing:

new Observable(...);

and

new BehaviorSubject(...);

in place of the hardcoded

X.create();

I was able to resolve all of my problems.

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

Webpack encountering issues with loading dependencies within dependencies

When I try to run webpack, it seems that the compiler is having trouble loading my app.module from within main.ts. Without using webpack, my application can find all modules correctly, but with Webpack, it's failing. This is my webpack configuration: ...

Enhancing the session object with new properties

I am attempting to include extra properties in the session object req.session.confirmationCode = confirmationCode; However, I encounter an error stating that the property confirmationCode does not exist Property 'confirmationCode' does not exist ...

Tips for displaying dynamic images using the combination of the base URL and file name in an *ngFor loop

I have a base URL which is http://www.example.com, and the file names are coming from an API stored in the dataSource array as shown below: [ { "bid": "2", "bnam": "ChickenChilli", "adds": "nsnnsnw, nnsnsnsn", "pdap": " ...

The error message "Property 'listingSub$' is not initialized in the constructor and is not definitely assigned" needs to be addressed and fixed in the code

import { Subscription } from "rxjs"; @Component({ selector: 'app-listing-detail', templateUrl: './listing-detail.component.html', styleUrls: ['./listing-detail.component.scss'] }) export class ListingDetailCo ...

Exploring NuxtJS Vuex Module namespaces and mutation enumerations

My NuxtJS website has a Vuex store with a root state and a module located at store/shop/cart/state.ts. Within the module, there is a file called store/shop/cart/mutations.ts. import { MutationTree } from 'vuex'; import { CartState } from './ ...

Removing fields when extending an interface in TypeScript

Attempting to extend the ISampleB interface and exclude certain values, like in the code snippet below. Not sure if there is an error in this implementation export interface ISampleA extends Omit<ISampleB, 'fieldA' | 'fieldB' | &apos ...

The type of the object is classified as 'unknown' (2571) while utilizing the map() function with an array containing objects

After researching this error extensively on Google and reading multiple posts, I am still unable to find a solution. I am trying to fetch data from an external API call that has the following signature: const properties: { [x: string]: unknown;} | { [x: s ...

Unable to trigger dispatchEvent on an input element for the Tab key in Angular 5

In my pursuit of a solution to move from one input to another on the press of the Enter key, I came across various posts suggesting custom directives. However, I prefer a solution that works without having to implement a directive on every component. My a ...

Angular 2: Harnessing the Power of Data-Binding with setTimeout

It appears there is an issue with changing a component's attribute inside a 'setTimeout' function during the initial page load. Consider having a component called 'HomeComponent' with the attribute: isValueTrue: boolean = false; ...

What is the syntax for creating a zip function in TypeScript?

If I am looking to create a zip function: function zip(arrays){ // assume more than 1 array is given and all arrays // share the same length const len = arrays[0].length; const toReturn = new Array(len); for (let i = 0; i < len; i+ ...

Issue NG0203 encountered during material import attempt

I've been encountering an issue with importing material. Despite using code similar to the examples on material.angular.io, I keep running into the ""inject() must be called from an injection context..." error. My goal is to create a simple table ...

Before users can apply any filters, all items must be loaded into an Observable<Hero[]> array

Is there a way to modify the Angular 2 Tour of Heroes search component so that it displays all items on page load (showing all Heroes) and then makes a new request to get filtered results only when a filter is provided? import { Component, OnInit } from & ...

Multiple Invocations of Angular NgrxStore Action Dispatched within Selector Function

Currently, I am working on an Angular project utilizing ngRx store for the first time. In this project, I need to dispatch an action to fetch users' courses after retrieving the user from the Store. However, I have encountered a problem where the acti ...

Establishing a Recyclable Testing Rendering Method in redux toolkit version 2

In the era of Redux Toolkit v2, a noticeable change occurred with the absence of the EmptyObject type and the unavailability of the PreloadedState type in the @reduxjs/toolkit package. This has led to a requirement of defining all reducers inside the pre ...

How to access the result without using subscribe in Angular?

I am facing unexpected behavior with a method in my component: private fetchExternalStyleSheet(outerHTML: string): string[] { let externalStyleSheetText: string; let match: RegExpExecArray; const matchedHrefs = []; while (match = this.hrefReg.exe ...

Run JavaScript code whenever the table is modified

I have a dynamic table that loads data asynchronously, and I am looking for a way to trigger a function every time the content of the table changes - whether it's new data being added or modifications to existing data. Is there a method to achieve th ...

Troubleshooting error in Angular 5 with QuillJS: "Parchment issue - Quill unable to

I've been working with the primeng editor and everything seems fine with the editor itself. However, I've spent the last two days struggling to extend a standard block for a custom tag. The official documentation suggests using the quilljs API fo ...

Generate a new data type based on the value of a single attribute within a collection of objects

Is there a way to extract a specific property of a combined type and generate a new type from it? Consider the following example: type Actions = | { type: "ADD_COLUMN"; newColumnIndex: number; column: SelectorColumnData; } | { type: ...

Is there a way to associate a click event with an angular2 template interpolation?

Can a click event be bound to an interpolation? Whenever I try to run the code below, I encounter the following ERROR Error: Uncaught (in promise): Error: Template parse errors: Parser Error: Got interpolation ({{}}) where expression was expected at col ...

The system encountered a TypeError: Unable to access the 'nativeElement' property as it is undefined

Hello, I am a beginner in Angular 2 and currently working on an image cropping plugin. My goal is to display the image on a canvas element. Below is my HTML code: <div class="row"> <div class="col-sm-6"> <canvas id="layout" width="40 ...