5

I'm trying to have an infinite scrolling section in my application. To achieve this I'm using this component to handle the scroll events and so on. When the scroll reaches the bottom of the div I'm calling a function to get more data. So far so good.

To make this function more efficient I'm trying to wait a few seconds before the call is made as well as make sure that the data is processed properly. To do this I've been looking at the example shown on the Angular website that showcases a wikipedia search.

I have a similar setup to what is being shown in the article, my problem is that I'm getting the following error when I call switchMap():

Type 'void' is not assignable to type 'ObservableInput<{}>'

This is a sample of my code:

private scrollEndActive: Subject<boolean> = new Subject<boolean>();

ngOnInit() {
    ...
    this.scrollEndActive
        .debounceTime(1000)
        .distinctUntilChanged()
        .switchMap(data => {
            // ... get data from server
        })
}

...

// event to trigger call to server
scrollEnd() {
    this.scrollEndActive.next(true);
}

With the code above this is what I'm getting:enter image description here

From the research I've made it seems to be an issue related to the fact that one should return the Observable (Type 'void' is not assignable to type 'ObservableInput<{}>'). But in my case I'm not sure what is the issue.

I'm working with:

  • Angular 4.0.1
  • TypeScript 2.2.2
  • RxJS 5.2.0
Community
  • 1
  • 1
Daniel Grima
  • 2,765
  • 7
  • 34
  • 58
  • You have to return `Observable` What is the problem with it? – yurzui May 18 '17 at 09:26
  • I'm not sure what I need to return up till this point... all the code I believe will be acting upon the `Subject` when it is triggered, so I'm not understanding where I should be returning the `Observable` – Daniel Grima May 18 '17 at 09:28
  • 3
    `.switchMap(data => { return Observable.of(null) })` Don't forget `import 'rxjs/add/observable/of';` But it is just stub. I assume you want to get real observable – yurzui May 18 '17 at 09:29
  • Ehh I feel a bit dumb... been trying something similar for a while.. must have overlooked something -_- thanks a lot! I think I will manage to get it to work - might be in need of a few mugs of coffee.. thanks again! – Daniel Grima May 18 '17 at 09:33
  • 2
    I wonder what's the point of using `.switchMap(data => { return Observable.of(null) })`. It looks like you don't need to be using `switchMap` at all. – martin May 18 '17 at 10:47
  • In my case I'm not returning `Observable.of(null)` I'm guessing yurzui was simply showing an example – Daniel Grima May 18 '17 at 11:12
  • probably something more like `.switchMap(data => fetch('/api/getAnswer?data=${data}')` – Brandon May 18 '17 at 14:12

2 Answers2

10

By default, an arrow function () => {...} has the return type void unless you return something.

If you want to use switchMap to return nothing, you can do as yurzui said in the comments, return Observable.empty().

That being said, if you return an observable of null in your switchMap, it means that you don't need switchMap and you can directly use do operator, that doesn an action without modifying returned data. Or mergeMap that allows you to return a new Observable from the data you got from the original one.

Supamiu
  • 8,501
  • 7
  • 42
  • 76
0

I'm working with:

  • Angular 5.1.0
  • TypeScript 2.5.3
  • RxJS 5.5.6

I had the same problem. I fixed put a return value into switchMap because you can't return an undefined or null value. But in case you can't return an Observable, you can return an empty array.

I had to solve an Observable chaining and I solved in this way:

resolve(): Observable<any> {
    return firstObservableFunc()
    .map(res => res)
    .switchMap(result => (result && result.value === 'OK') ? secondObservableFunc() : []);                        
}