4

I am currently trying to send data between components via a data service using "BehaviorSubject". In the first component, I am updating the messageSoruce and in the second component , retrieving the data but it is empty. I checked that the value "this.card.img" is not empty. What am I missing ?

Data Service

import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';


@Injectable()
export class DataService {

private messageSource = new BehaviorSubject("")
currentMessage = this.messageSource.asObservable();

constructor() { }

  changeMessage(message: string) {
  this.messageSource.next(message)
    }

 }

First component

import {Component} from '@angular/core';
import {Router} from '@angular/router';
import {DataService} from 'src/app/services/data/data.service';


@Component({
  selector: 'app-card',
  templateUrl: './card.component.html',
  providers: [ DataService ],
  styleUrls: ['./card.component.css']
})


export class CardComponent {



  @Input('card') card:Card 


  constructor(public router: Router,
              public dataService :DataService ) {

  }

  openDetails() {

   this.dataService.changeMessage(this.card.img)
   this.router.navigateByUrl('/imganalyse');

  }

}

Second component

import { Component, OnInit, } from '@angular/core';
import {DataService} from '../../services/data/data.service'

@Component({
  selector: 'app-imganalyse',
  templateUrl: './imganalyse.component.html',
  providers: [ DataService ],
  styleUrls: ['./imganalyse.component.css']
})



export class ImganalyseComponent implements OnInit {

  channel: string;

  constructor(private  youtubeService:YoutubeService,
              private dataService:DataService) { 

  }

  ngOnInit() {

  this.dataService.currentMessage.subscribe(channel => this.channel = channel)


  console.log(this.channel)

  }

}
mruanova
  • 6,351
  • 6
  • 37
  • 55
Eltomon
  • 354
  • 3
  • 16
  • Did you realize that in your second component you are trying to set `this.channe` instead of `this.channel` ? – Zachary Bennett Feb 17 '19 at 04:45
  • when copying and inserting I made a mistake, the value is this.channel – Eltomon Feb 17 '19 at 10:35
  • Is there any way you can create a stack blitz of this or paste html templates as well. I will say one thing, just stylistically, the Angular convention when working with Observables is to end variable names with a `$`. So, in your DataService, `currentMessage` should be `currentMessage$` unless you/your organization doesn't care. – Zachary Bennett Feb 17 '19 at 12:38
  • The providers: [DataServie] needs only to be set in app.module.ts to use only one instance. – Eltomon Feb 18 '19 at 21:55

2 Answers2

2

Solution:

The providers: [DataServie] needs only to be set in app.module.ts to only use one instance. In my case every component had his own dataservice provider , therefore it had more than one instance ...(that's the reason why it was always empty)

Eltomon
  • 354
  • 3
  • 16
1

First, when you declare DataService in the component providers, it creates a new instance. This means that FirstComponent.dataService refers to a different object than SecondComponent.dataService. Remove the 'providers' property from your component decorators and add 'providedIn' to your DataService decorator to make it a singleton so all references will refer to the same instance (unless you put it in a class's 'providers'):

@Injectable({
    providedIn: 'root'
})
export class DataService {

You are logging outside the subscription. When you call this:

this.dataService.changeMessage(this.card.img)

In your second component you have this in the OnInit:

this.dataService.currentMessage.subscribe(channel => this.channel = channel)
console.log(this.channel)

So you subscribe and do nothing but set the channel when it is changed, but your log happens immediately, so this.channel will not be set yet. I don't know what is calling openDetails(), but try this in your second component:

this.dataService.currentMessage.subscribe(channel => {
  this.channel = channel;
  console.log('updated channel:', channel);
});



Jason Goemaat
  • 28,692
  • 15
  • 86
  • 113