Paul Cavacas
Paul Cavacas

Reputation: 4454

What is wrong with this operator being undefined

I have a component that has the following lines in the ngOnInit method

    this.businessTypesService.get()
        .subscribe((businessTypes: string[]) => {
            _.each(businessTypes,
                (businessType: string) => {
                    this.businessTypes.push({ label: businessType, value: businessType });
                });
        });

Now I have this same type of block 10 times each loading different drop lists of options. Each is the same except for which service it calls and which array it pushes the results into, so I want to refactor this into a single method, so that I can change the code to something like this.

this.loadReferenceList(this.businessTypesService.get, this.businessTypes);

and the new loadReferenceList method looks like this

loadReferenceList(loadMethod: () => Observable<string[]>, lookupList: SelectItem[]): any {
    loadMethod()
        .subscribe(((items: string[]) => {
            _.each(items,
                (item: string) => {
                    lookupList.push({ label: item, value: item });
                });
        }));
}

Each of the service classes look like this

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';

@Injectable()
export class BusinessUnitsService {

    get(): Observable<string[]> {
        return Observable.of(this.getData());
    }

    constructor(private readonly http: Http) { }

    getData(): string[] {
        return [
            'Beverage',
            'Food',
            'Beverage & Food',
            'Promo Pack'
        ];
    }

}

Right now it is just hard coded data, but will be changed to use Http to pull down the real values later.

The problem is that the this.getdata() line is failing saying that this is undefined. I don't understand why this would be undefined when I change it around to be called like this.

********Answer************ I made the following changes to get this to work based off of the answer below the loadReferenceList method was changed to look like this. Basically added a parameter for the service, so that I could have a reference to what this was supposed to be and then added the .bind method to give the method scope.

loadReferenceList(loadMethod: () => Observable<string[]>, service: any, lookupList: SelectItem[]): any {
    const method = loadMethod.bind(service);

    method()
        .subscribe(((items: string[]) => {
            _.each(items,
                (item: string) => {
                    lookupList.push({ label: item, value: item });
                });
        }));
}

Upvotes: 0

Views: 60

Answers (2)

s-f
s-f

Reputation: 2141

You either need to bind your .get() to your object, i.e.

loadReferenceList(this.businessTypesService.get.bind(this.businessTypesServices), ...)

or you need to define abstract interface for all services and pass objects as is

loadReferenceList(service: AbstractService, ...) { service.get() } all your services need to implement this interface

Upvotes: 1

Pezetter
Pezetter

Reputation: 2862

I made a live simple version of what you're doing.

I was having problems using Observable.of(...). It worked when i used Observable.create(...) and new Observable(...).

With pretty much anything that has to do with rxjs, I use a plunkr like this to test. Let me know if it helps?

Upvotes: 0

Related Questions