Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting "Cannot read property 'http' of undefined" with Angular 7

I'm working on an Angular 7 project, and I'm facing a weird problem that took me some considerable time to identify, but I don't know why this is happening and I hope you guys can help me. I created a service using angular-cli, and then I implemented it as follows:


    import {Injectable} from '@angular/core';
    import {HttpClient} from "@angular/common/http";
    import {forkJoin, Observable} from "rxjs";
    import {map} from "rxjs/operators";

    @Injectable({
      providedIn: 'root'
    })
    export class SampleService {

      constructor(private http: HttpClient) {
      }

      save(sample: Sample): Observable {
        return this.http.post("http://localhost:3000/samples", sample).pipe(map(this.parser));
      }

      saveAll(samples: Sample[]): Observable {
        return forkJoin(samples.map(this.save))
      }

      private parser = (value): Sample => new Sample(value.name);
    }

    export class Sample {
      name: string;

      constructor(name: string) {
        this.name = name;
      }
    }

I put a breakpoint on each method. When I run it I get the following:

First breakpoint stop

As you can see, everything seems ok in the first breakpoint, so let's go to the next.

Second breakpoint stop

Now everything is undefined, and I get the following error in the console:


    ERROR TypeError: Cannot read property 'http' of undefined

If I change this line:


    forkJoin(samples.map(this.save))

to


    forkJoin(samples.map(sample => this.save(sample)))

When I rerun the code. I get:

Third breakpoint stop

And now everything seems to be ok, and the code works just fine. As a java developer, in a similar situation, the first way is comparable to a method reference and it would work just fine, why in TypeScript it doesn't?

like image 826
Felipe Belluco Avatar asked Oct 27 '22 22:10

Felipe Belluco


1 Answers

this is contextual. Every function defined using function definition gets its own this. Arrow function definition works differently in that, it binds the parent context to the function body, making this refer to the parent this. It is similar to defining a function and binding it explicitly like:

function(doc){
//function body
}).bind(this)
like image 95
Aragorn Avatar answered Nov 18 '22 11:11

Aragorn