4

I have an AlertService which has confirm box. I am calling that from my service. If user hits Yes, then I want to call a REST service. But I am getting this error:

I believe since I am calling from inside alertService.confirm(), and alertService does not have http declared, I am gettgn this error. But I am not sure what the appropriate way to resolve this.

ERROR TypeError: Cannot read property 'http' of undefined
    at inspection.service.ts:91
    at Object.siFn (alert.service.ts:53)
    at Object.eval [as handleEvent] (AlertComponent.html:25)
    at handleEvent (core.es5.js:11998)
    at callWithDebugContext (core.es5.js:13467)
    at Object.debugHandleEvent [as handleEvent] (core.es5.js:13055)
    at dispatchEvent (core.es5.js:8614)
    at core.es5.js:9228
    at HTMLAnchorElement.<anonymous> (platform-browser.es5.js:2648)
    at ZoneDelegate.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)

inspection.component.ts

import {Component, OnInit, Input, ViewChild} from "@angular/core";
import {Headers, Http} from "@angular/http";
import {Router} from "@angular/router";
import {NgModel, FormGroup} from "@angular/forms";
    sendMesage(inspection) {
          this.inspectionService.sendMesage(inspection);
    }

inspection.service.ts

import {Headers, Http}  from "@angular/http";
import {Observable} from 'rxjs/Observable';
import {Subject} from "rxjs";
import {of} from 'rxjs/observable/of';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Injectable}     from "@angular/core";
import {Component, OnInit, ViewChild} from "@angular/core";
import {Router} from "@angular/router";
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';
    constructor(private http: Http,
                    private router: Router,
                    private alertService: AlertService) {
      }

        sendMesage(inspection: Inspection) {
             this.alertService.confirm("Threshold reached for Rank " + inspection.rankName + ". Do you want send message ?",function(){
                alert("1...");
                const url = '/api/inspection/sendmessage/';
                 this.http
                    .post(url, JSON.stringify(inspection), {headers: this.headers})
                    .toPromise()
                    .then(response => {
                        let data = response.json();
                        return response.json() as Inspection;
                })
                .catch(error => {
                    alert("error");
                });
            },function(){
              alert("No clicked"); 
            })
        }

app.module.ts

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';
import { HttpClientModule } from '@angular/common/http';

import {AppRoutingModule } from './app-routing.module';

import {InspectionService} from './inspection/inspection.service';
import {AlertService} from './alert/alert.service';

import {AppComponent} from './app.component';
import {AlertComponent} from './alert/alert.component';
import {NavigationComponent} from './navigation/navigation.component';
import { InspectionComponent } from './inspection/inspection.component';

@NgModule({
    imports: [
        BrowserModule,
        HttpClientModule,
        FormsModule,
        HttpModule,
        AppRoutingModule
    ],
    providers: [
        AlertService,
        InspectionService,
    ],
    declarations: [
        AppComponent,
        AlertComponent,
        NavigationComponent,
        InspectionComponent,
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

alert.service.ts

import {Injectable} from '@angular/core';
import {Router, NavigationStart} from '@angular/router';
import {Observable} from 'rxjs';
import {Subject} from 'rxjs/Subject';

import { AlertComponent } from './alert.component';

@Injectable()
export class AlertService {
  private subject = new Subject<any>();
  private keepAfterNavigationChange = false;

  constructor(private router: Router) {
    // clear alert message on route change
    router.events.subscribe(event => {
      if (event instanceof NavigationStart) {
        if (this.keepAfterNavigationChange) {
          // only keep for a single location change
          this.keepAfterNavigationChange = false;
        } else {
          // clear alert
          this.subject.next();
        }
      }
    });
  }

  success(message: string, keepAfterNavigationChange = false) {
    this.keepAfterNavigationChange = keepAfterNavigationChange;
    this.subject.next({type: 'success', text: message});
  }

  error(message: string, keepAfterNavigationChange = false) {
    this.keepAfterNavigationChange = keepAfterNavigationChange;
    this.subject.next({type: 'error', text: message});
  }

  getMessage(): Observable<any> {
    return this.subject.asObservable();
  }

  confirm(message: string,siFn:()=>void,noFn:()=>void){
    this.setConfirmation(message,siFn,noFn);
  }

  setConfirmation(message: string,siFn:()=>void,noFn:()=>void) {
        let that = this;
        this.subject.next({ type: "confirm",
                    text: message,
                    siFn:
                    function(){
                        that.subject.next(); //this will close the modal
                        siFn();
                    },
                    noFn:function(){
                        that.subject.next();
                        noFn();
                    }
        });

  }
}
19
  • Please, post your AlertComponent.html (line 25) too, as indicated by the console. Commented Apr 17, 2018 at 16:16
  • In your module are you importing HttpClientModule or HttpModule? Commented Apr 17, 2018 at 16:17
  • the entire code (actually almost) is here: stackoverflow.com/questions/49868519/… Commented Apr 17, 2018 at 16:19
  • 1
    Possible duplicate of How to access the correct `this` inside a callback? Commented Apr 17, 2018 at 16:19
  • @AlexanderStaroselsky: Updated my code. Added dimports Commented Apr 17, 2018 at 16:21

1 Answer 1

6

When using javascript callback function declare

var that = this;

then use that.http as your this.http as below in your

inspection.service.ts

sendMesage(inspection: Inspection) {
         var that = this;
         this.alertService.confirm("Threshold reached for Rank " + inspection.rankName + ". Do you want send message ?",function(){
            alert("1...");
            const url = '/api/inspection/sendmessage/';
             that.http
                .post(url, JSON.stringify(inspection), {headers: that.headers})
                .toPromise()
                .then(response => {
                    let data = response.json();
                    return response.json() as Inspection;
            })
            .catch(error => {
                alert("error");
            });
        },function(){
          alert("No clicked"); 
        })
    }
Sign up to request clarification or add additional context in comments.

1 Comment

perfect. Works like charm!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.