Angular 4 Subscribing to observable is not updating after change

11,455

You subscribe to an observable, and then you replace that observable by another one.

That's like giving someone an email address where he can read mails you send to him, but then replacing that email address by another one every time you send an email. Obviously, the receiver will never receive your mails if you send them to a different address.

You need to use the same, unique observable, and make it emit a new event. Using a Subject is the easiest way to do that:

banners$: Subject<any[]> = new BehaviorSubject<any[]>([]);

setBanners(banners: any[]): void {
    this.banners$.next(banners);
}
Share:
11,455
Steve
Author by

Steve

HTML, CSS, SASS, JavaScript, jQuery, etc...

Updated on June 14, 2022

Comments

  • Steve
    Steve almost 2 years

    I have a service with an observable which is being subscribed to via a component. This seems to work as the subscriber is showing the initial value. I have another component which is then updating the observable however the new value does not get shown.

    Service:

    import { Injectable } from '@angular/core';
    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/observable/of'; 
    
    @Injectable()
    
    export class BannerService {
    
        banners$: Observable<any[]> = Observable.of([]);
    
        getBanners(): Observable<any[]> {
            return this.banners$;
        }
    
        setBanners(banners: any[]): void {
            this.banners$ = Observable.of(banners);
        }
    
    }
    

    Component with subscriber:

    import { Component, ViewEncapsulation, OnInit } from '@angular/core';
    
    import { BannerService } from './../banner/banner.service';
    
    @Component({
        selector: '.banner',
        templateUrl: './banner.component.html',
        styleUrls: ['./banner.component.sass'],
        encapsulation: ViewEncapsulation.None
    })
    
    export class BannerComponent implements OnInit {
    
        constructor(private bannerService: BannerService){}
    
        ngOnInit() {
            this.bannerService.banners$.subscribe(banners => {
                console.log(banners);
            });
    
        }
    }
    

    Component with setter:

    import { Component, ViewEncapsulation, OnInit } from '@angular/core';
    
    import { BannerService } from './../banner/banner.service';
    
    @Component({
        selector: '.home-component',
        templateUrl: './home.component.html',
        styleUrls: ['./home.component.sass'],
        encapsulation: ViewEncapsulation.None
    })
    
    export class HomeComponent implements OnInit {
    
        data = {
            banners: [
                {
                    title: 'Title 1',
                    image: '../images/image1.jpg'
                },
                {
                    title: 'Title 2',
                    image: '../images/image2.jpg'
                },
                {
                    title: 'Title 3',
                    image: '../images/image3.jpg'
                }
            ]
        }
    
        constructor(private bannerService: BannerService){}
    
        ngOnInit(): void {
            this.bannerService.setBanners(this.data.banners);
        }
    
    }
    

    Any help would be really appreciated, I've tried a bunch of different things and can't get it working.