API查询在ngOnInit中是从前一个组件中执行的。

huangapple go评论59阅读模式
英文:

API queries in ngOnInit are executed from previous component

问题

I have signin.component.ts:

 ngOnInit() {
    this.metaService.getMetaCompany().subscribe((response: Json) => {
      console.log('meta company');
    });
  }

and app.component.ts:

 ngOnInit() {
    if (authenticated) {
     this.metaService.getMetaCompany().subscribe((response: Json) => {
       console.log('meta company');
     });
   }
  }

meta.service.ts:

getMetaCompany(): Observable<Json | JsonError> {
 return this.http
  .get<Json | JsonError>(this.getMetaCompanyUrl)
  .pipe(
    catchError(this.errorService.handleError)
 );
}

app-routing.module.ts:

...
const routes: Routes = [
  { path: 'signin', loadChildren: () => import('./signin/signin.module').then(m => m.SignInModule) },
  { path: 'inbox', loadChildren: () => import('./inbox/inbox.module').then(m => m.InboxModule) },
  { path: 'work', loadChildren: () => import('./work/work.module').then(m => m.WorkModule) },
  { path: 'something-went-wrong', component: InternalServerErrorComponent },
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
  exports: [RouterModule]
})
export class AppRoutingModule { }

app.module.ts:

...
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    BrowserAnimationsModule,
    RouterModule,
    AppRoutingModule
  ],
  providers: [...],
  bootstrap: [AppComponent]
})

export class AppModule { }

Redirection I execute with using these commands:

from sign out to sign in:

this.router.navigate(['signin'], { queryParams: { r: this.sharedService.currentUrl }});

from signin to another:

this.router.navigateByUrl(this.returnUrl);

When I'm on sign in page it's executed API query once, everything is fine, but after successful login I redirected to another page and in console log I see API query is executed twice: from app.component and signin.component.

I can't understand why I see queries from previous component (signin).
The same situation with sign out. I'm sign out and redirect to login page but API requests from ngOnInit of any previous component (it doesn't depend on page) are executed for some reasons and I'm getting errors because user was already signed out. Everything works fine between pages/components when user was logged in.

So how can I avoid executing API queries from previous component?

英文:

I have
signin.component.ts:

 ngOnInit() {
    this.metaService.getMetaCompany().subscribe((response: Json) =&gt; {
      console.log(&#39;meta company&#39;);
    });
  }

and app.component.ts:

 ngOnInit() {
    if (authenticated) {
     this.metaService.getMetaCompany().subscribe((response: Json) =&gt; {
       console.log(&#39;meta company&#39;);
     });
   }
  }

meta.service.ts:

getMetaCompany(): Observable&lt;Json | JsonError&gt; {
 return this.http
  .get&lt;Json | JsonError&gt;(this.getMetaCompanyUrl)
  .pipe(
    catchError(this.errorService.handleError)
 );
}

app-routing.module.ts:

...
const routes: Routes = [
  { path: &#39;signin&#39;, loadChildren: () =&gt; import(&#39;./signin/signin.module&#39;).then(m =&gt; m.SignInModule) },
  { path: &#39;inbox&#39;, loadChildren: () =&gt; import(&#39;./inbox/inbox.module&#39;).then(m =&gt; m.InboxModule) },
  { path: &#39;work&#39;, loadChildren: () =&gt; import(&#39;./work/work.module&#39;).then(m =&gt; m.WorkModule) },
  { path: &#39;something-went-wrong&#39;, component: InternalServerErrorComponent },
  { path: &#39;**&#39;, component: PageNotFoundComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { relativeLinkResolution: &#39;legacy&#39; })],
  exports: [RouterModule]
})
export class AppRoutingModule { }

app.module.ts:

...
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    BrowserAnimationsModule,
    RouterModule,
    AppRoutingModule
  ],
  providers: [...],
  bootstrap: [AppComponent]
})

export class AppModule { }

Redirection I execute with using these commands:

from sign out to sign in:

this.router.navigate([&#39;signin&#39;], { queryParams: { r: this.sharedService.currentUrl }});

from signin to another:

this.router.navigateByUrl(this.returnUrl);

When I'm on sign in page it's executed API query once, everything is fine, but after successful login I redirected to another page and in console log I see API query is executed twice: from app.component and signin.component.

I can't understand why I see queries from previous component (signin).
The same situation with sign out. I'm sign out and redirect to login page but API requests from ngOnInit of any previous component (it doesn't depend on page) are executed for some reasons and I'm getting errors because user was already signed out. Everything works fine between pages/components when user was logged in.

So how can I avoid executing API queries from previous component?

答案1

得分: 1

这被称为Api订阅的内存泄漏,

最佳实践是在导航到其他组件之前,在当前组件中销毁您的订阅。

按照以下步骤操作:

  1. 在构造函数之前从'rxjs/internal/Subject'中添加Subject。

    destroy$: Subject&lt;boolean&gt; = new Subject&lt;boolean&gt;();

  2. 在每次api调用之前的订阅之前添加以下管道。

    .pipe(takeUntil(this.destroy$))

  3. 最后,实现OnDestory钩子以销毁所有上述订阅。

    ngOnDestroy(): void { this.destroy$.next(true); this.destroy$.unsubscribe(); }

英文:

This is called as Memory Leakage by Api Subscription,

The best practice is to destroy your subscription in current component before you navigate to other component.

Follow the steps to do the same.

  1. Add the Subject from 'rxjs/internal/Subject' just before the constructor.

    destroy$: Subject&lt;boolean&gt; = new Subject&lt;boolean&gt;();

  2. Add the below pipe to every api call before subscription

    .pipe(takeUntil(this.destroy$))

  3. And finally implement the OnDestory hook with destroying all above subscription.

    ngOnDestroy(): void {
    this.destroy$.next(true);
    this.destroy$.unsubscribe();
    }

huangapple
  • 本文由 发表于 2023年5月10日 19:53:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76218076.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定