最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - BehaviorSubject: next is not a function - Stack Overflow

programmeradmin0浏览0评论

I am trying share data between sibling ponents and do this via a shared service. When the first ponent 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 ponent 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-selectponent.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 ponent
  public change = (event: any) => {
    console.log(event);
    this.dashboardService.selectedServer.next(event);
  }

}

Detail ponent:

@Component({
  selector: 'app-server-details',
  template: `
  <section>
  <div class="form-group">
    <label>Description</label>
    <input type="text" [(ngModel)]="server">
  </div>
</section>
  `,
  styleUrls: ['./server-detailsponent.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-selectponent.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';

I am trying share data between sibling ponents and do this via a shared service. When the first ponent 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 ponent 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.ponent.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 ponent
  public change = (event: any) => {
    console.log(event);
    this.dashboardService.selectedServer.next(event);
  }

}

Detail ponent:

@Component({
  selector: 'app-server-details',
  template: `
  <section>
  <div class="form-group">
    <label>Description</label>
    <input type="text" [(ngModel)]="server">
  </div>
</section>
  `,
  styleUrls: ['./server-details.ponent.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.ponent.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';
Share Improve this question edited Dec 20, 2017 at 10:35 martin 97.1k26 gold badges204 silver badges236 bronze badges asked Dec 20, 2017 at 9:36 Christophe LoeysChristophe Loeys 1962 silver badges11 bronze badges 7
  • can you show from where you are importing behavioursubject in your dashboard service class – Karan Garg Commented Dec 20, 2017 at 9:54
  • @KaranGarg See my edit :) – Christophe Loeys Commented Dec 20, 2017 at 9:58
  • can you try this import import { BehaviorSubject } from 'rxjs/Rx'; – Karan Garg Commented Dec 20, 2017 at 10:05
  • Could you try to type your variable like selectedServer: BehaviorSubject<Server> = new BehaviorSubject(null); – user4676340 Commented Dec 20, 2017 at 10:06
  • Dont import from rxjs/Rx – Jota.Toledo Commented Dec 20, 2017 at 10:06
 |  Show 2 more ments

1 Answer 1

Reset to default 6

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)".

发布评论

评论列表(0)

  1. 暂无评论