This question has already been answered:

I am developing a component responsible for authorization in an Angular2 application. Component Code:

import { Component, OnInit } from '@angular/core'; import { IAuthData } from './auth-data'; import { IAuthResult } from './auth-result'; import { AuthorizationService } from './authorization.service'; import { NotificationsService } from 'angular2-notifications'; @Component({ templateUrl: 'authorization.component.html', styleUrls: [ 'authorization.component.css' ], moduleId: module.id }) export class AuthorizationComponent implements OnInit { private _authorizationService: AuthorizationService; private _notificationsService: NotificationsService; constructor(private authorizationService: AuthorizationService, private notificationsService: NotificationsService) { this._authorizationService = authorizationService; this._notificationsService = notificationsService; } public pageTitle: string = 'Авторизация'; public login: string; public password: string; ngOnInit() : void { } authorize(): void { this._notificationsService.info(this.pageTitle, `Попытка авторизации пользователя "${this.login}": запрос отправлен на сервер.`); this._authorizationService.authorize(<IAuthData>{ login: this.login, hash: this.password }) .subscribe(authResult => { let message: string = `"${this.login}": ${authResult.message}`; if (authResult.isAuthorized) { this._notificationsService.info(this.pageTitle, message); } else { this._notificationsService.error(this.pageTitle, message); } }); } } 

This option works, however, when refactoring, I decided to render the lambda, which is passed to the subscribe method in a separate method:

 private processAuthResult(authResult: IAuthData): void { let message: string = `"${this.login}": ${authResult.message}`; if (authResult.isAuthorized) { this._notificationsService.info(this.pageTitle, message); } else { this._notificationsService.error(this.pageTitle, message); }let message: string = `"${this.login}": ${authResult.message}`; if (authResult.isAuthorized) { this._notificationsService.info(this.pageTitle, message); } else { this._notificationsService.error(this.pageTitle, message); } } authorize(): void { this._notificationsService.info(this.pageTitle, `Попытка авторизации пользователя "${this.login}": запрос отправлен на сервер.`); this._authorizationService.authorize(<IAuthData>{ login: this.login, hash: this.password }) .subscribe(this.processAuthResult); } 

If you organize the code in a similar way, the field this._notificationsService is undefined . What could be the reason?

Reported as a duplicate at Grundy. javascript Mar 31 '17 at 11:34 .

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

  • Please add the code of the authorize method after refactoring - kmv
  • @kmv, everything added. - klutch1991

1 answer 1

It's not about the access modifier, but about changing the context of this . You need to keep the context:

 authorize(): void { this._notificationsService.info(this.pageTitle, `Попытка авторизации пользователя "${this.login}": запрос отправлен на сервер.`); this._authorizationService.authorize(<IAuthData>{ login: this.login, hash: this.password }) .subscribe(authResult => this.processAuthResult(authResult)); } } 
  • I tried it - it works. Can you explain in more detail what exactly you wrote? - klutch1991
  • look in subscribe this still a link to your AuthorizationComponent , but when you call the processAuthResult method it is called with another this - Kostiantyn Okhotnyk
  • one
    I think in this context it will even work if self.processAuthResult.call(self, authResult ) replaced by this.processAuthResultl(authResult ) - Zugr
  • More about call context - Kostiantyn Okhotnyk
  • 2
    call here is superfluous - and without it everything will work. In fact, the problem was corrected by lambda :-) - Pavel Mayorov