Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4 Subscribing to observable is not updating after change

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.

like image 414
Steve Avatar asked Dec 04 '22 21:12

Steve


1 Answers

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);
}
like image 111
JB Nizet Avatar answered Dec 29 '22 08:12

JB Nizet