Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BehaviorSubject: next is not a function

I am trying share data between sibling components and do this via a shared service. When the first component loads, it retrieves a list of Servers from my API and fills a select-box with all the retrieved servers. Now I want to notify my other component when the user selected a new Server so I can display it's details.

This is my service:

@Injectable()
export class DashboardService {
    servers: Server[] = [];
    selectedServer = new BehaviorSubject<Server>(null);

    setServers(servers: Server[]) {
        this.servers = servers;
    }

}

Component with the select-box:

@Component({
  selector: 'app-servers-select',
  template: `
    <div class="form-group">
      <label>Server</label>
      <select class="form-control" [(ngModel)]="this.dashboardService.selectedServer" (ngModelChange)="change($event)">
        <option disabled>-- Select server --</option>
        <option *ngFor="let server of servers" [ngValue]="server">{{server.Name}}</option>
      </select>
    </div>`,
  styleUrls: ['./servers-select.component.css'],
  providers: [ServerService]
})
export class ServersSelectComponent implements OnInit {
  servers: Server[] = [];

  constructor(private serverService: ServerService, private dashboardService: DashboardService) { }
  ngOnInit() {
    this.serverService
      .getServers()
      .subscribe(s => {
        this.servers = s;
        this.dashboardService.setServers(s);
        console.log(s);
      },
      e => console.log(e));

  }

  // todo: pass to dashboard component
  public change = (event: any) => {
    console.log(event);
    this.dashboardService.selectedServer.next(event);
  }

}

Detail component:

@Component({
  selector: 'app-server-details',
  template: `
  <section>
  <div class="form-group">
    <label>Description</label>
    <input type="text" [(ngModel)]="server">
  </div>
</section>
  `,
  styleUrls: ['./server-details.component.css']
})
export class ServerDetailsComponent implements OnInit {

  private server: Server = null;

  constructor(private dashboardService: DashboardService) { }

  ngOnInit() {
    this.dashboardService.selectedServer.subscribe((value: Server) => {
      console.log(value + 'lalalal');
      this.server = value;
    });
  }

}

When I select a new Server, the change() method gets called correctly, but throws the following error in the console:

ERROR TypeError: _this.dashboardService.selectedServer.next is not a function at ServersSelectComponent.change (servers-select.component.ts:39)

The subscribe seems to work already since I get 'nulllalalal' in my console. What am I missing?

EDIT: - I am using angular 5 and rxjs 5.5.2 - In my DashboardService, I import BehaviorSubject as follows:

import { BehaviorSubject } from 'rxjs/BehaviorSubject';
like image 701
Christophe Loeys Avatar asked Dec 20 '17 09:12

Christophe Loeys


1 Answers

In ServersSelectComponent's template you have:

[(ngModel)]="this.dashboardService.selectedServer"

This overrides the selectedServer service property with a value of one of the options.

If you want to emit changes via a RxJS Subject you definitely don't want to be using [(ngModel)] and trigger the change manually with (change) event listener like (change)="change($event)".

like image 152
martin Avatar answered Nov 04 '22 01:11

martin