Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to avoid infinit self calls #24

Open
stkevintan opened this issue Jun 17, 2019 · 3 comments
Open

How to avoid infinit self calls #24

stkevintan opened this issue Jun 17, 2019 · 3 comments
Labels

Comments

@stkevintan
Copy link

if we invoke else service method suck as this.getActions() inside the effectActions[actionName] function in sync way, it will cause an error:

InternalError: "too much recursion"

the effect can be:

  @Effect()
  fetchInfo(url$: Observable<string>):Observable<EffectAction> {
    return url$.pipe(
      switchMap(url => from(client.get(url))),
      mergeMap(data => of(this.getActions().setData(data), this.getActions().setLoading(false))),
      startWith(this.getActions().setLoading(true)),
    )
  }

the effect init function is :

const effect$: Observable<EffectAction> = effectActions[actionName](payload$, state$)

because the startWith is sync, so this.getActions() will request the ikari instance, but the ikari instance is not fully constructed at that time. so it will invoke the create function again and agian...

@stkevintan
Copy link
Author

I try to fix it by rewrite some souce code as follow, but I dont known if it has some bad side effects or not

from:

actions[actionName] = (payload: any) => payload$.next(payload)

to:

   const payload$ = new BehaviorSubject<any>(undefined)
    actions[actionName] = (payload: any) => {
      payload$.next(payload)
    }
    const effect$: Observable<EffectAction> = from(Promise.resolve()).pipe(
      switchMap(() => effectActions[actionName](payload$, state$))
    )

@runjuu
Copy link
Contributor

runjuu commented Jun 17, 2019

@Effect()
  fetchInfo(url$: Observable<string>):Observable<EffectAction> {
    return url$.pipe(
      switchMap(url => from(client.get(url))),
      mergeMap(data => of(this.getActions().setData(data), this.getActions().setLoading(false))),
-     startWith(this.getActions().setLoading(true)),
    )
  }

I think that the issue is caused by the startWith operator. How about:

@Effect()
  fetchInfo(url$: Observable<string>):Observable<EffectAction> {
    return url$.pipe(
      switchMap(url => from(client.get(url))),
      mergeMap(data => of(
        this.getActions().setLoading(true),
        this.getActions().setData(data),
        this.getActions().setLoading(false)
      )),
    )
  }

Maybe we should show some tips about misuse the startWith operator? 🤔️

@stkevintan
Copy link
Author

stkevintan commented Jun 17, 2019

@runjuu
I think we should tell user not use this in sync context include startWith, such as :

@Effect()
fetchInfo(url$: Observable<string>):Observable<EffectAction> {
    this.getState()    //  Error 
    this.getState$()  //  Error
    this.getActions() //  Error
    return url$.pipe(
      switchMap(url => from(client.get(url))),
      mergeMap(data => of(
        this.getActions().setLoading(true),
        this.getActions().setData(data),
        this.getActions().setLoading(false)
      )),
    )
  }

or we can do something avoid this error ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants