Reactive-Extensions / RxJS

The Reactive Extensions for JavaScript
http://reactivex.io
Other
19.49k stars 2.1k forks source link

Cannot assign to a services local variable using observables #1490

Closed mogwai closed 7 years ago

mogwai commented 7 years ago

Summary

In an angular app, I'm trying to cache HTTP results into a local variable by assigning the JobService jobs:Job[] variable to the result of the request. I then wish to filter the results invoking the setSearch() function from another component that injects the JobService.

When the UserService retrieves the user, the JobService subscribes to the event and gets the jobs. This means that if the user state changes so does the jobs array. This then invokes setJobs() to set the local jobs variable

Later when a user types in the search box, setSearch() is called and this.jobs is an empty array even though it was set in setJobs()

The jobsPublisher then publishes this new set of jobs to the subscribers.

Note: HttpCacheService is very similar to Http but it just maps the response to the object desired, whilst handling and logging errors.

Code

@Injectable()
export class JobService {
    jobsPublisher: BehaviorSubject<Job[]>
    jobs: Job[] = []

    constructor(
        private http: HttpCacheService<Job[]>,
        private userService: UserService,
        private searchService: SearchService
    ) {
        this.jobsPublisher = new BehaviorSubject<Job[]>(this.jobs)

        this.userService.userPublisher.subscribe((user: User) => {
            this.getJobs()
        })
    }

    private getJobs(): void {
        let req = this.http.GET("/d/jobs").subscribe(jobs => {
            this.setJobs(jobs) // jobs = Array(100)
            this.jobsPublisher.next(jobs)
            req.unsubscribe()
        })
    }

    private setJobs(jobs) {
        console.log("Setting jobs!")
        this.jobs = jobs // this.job = jobs = Array(100)
    }

    setSearch(query: string) { // this.jobs = []
        let newJobs = this.filterJobs(query, this.jobs)
        console.log(`Job Length Filter [${this.jobs.length}] -> [${newJobs.length}]`)
        this.jobsPublisher.next(newJobs)
    }

    private filterJobs(query: string, jobs: Job[]): Job[] {
            // Filter jbos
    }
}

Demos

I've created a working example and a broken example.

Jobs becomes empty after assignment Variable is assigned

Environment

Browser: Chrome (desktop) version XX

For Tooling issues:

mogwai commented 7 years ago

I was splicing the jobs variable in the component