简体   繁体   中英

Typescript async and this scope

I've set up a simple service to pull data from a db, the service works fine but when I try to take the data from the service and into a component via an aysnc function, I can't seem to pass the scope of the function through using "this".

Any ideas? I must be doing something obviously wrong as I'm new to development.

Here's the service code which works fine;

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

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

  constructor(private http: HttpClient) { }

  httpGetFeatures() {
    console.log("inFeatures")
    this.http.post("http://******************",
  {
         "command": "get_feature",
         "classes":"F,G"
  })

  .subscribe(
         (val) => {
        console.log("inSubscribe")
        console.log(val)
          return(val)
          //this.parseFeatures(val)
         },
         response => {
         console.log("POST call in error", response);
         },
                 () => {
  });
  }



  parseFeatures (val: any) {
    console.log("in parse Features")
    console.log(val)
  }



}

and here is the component TS, the problem is "this" throws an error because it's undefined as I believe the scope of this isn't being passed through. Its the final async function at the bottom.

import { Component, OnInit } from '@angular/core';
import * as data from "./testfile.json";
import * as catdata from "../categories/cattestfile.json";
import {VenueserviceService} from "../../services/venueservice.service"


@Component({
  selector: 'app-homepage',
  templateUrl: './homepage.component.html',
  styleUrls: ['./homepage.component.css']
})
export class HomepageComponent implements OnInit {

  constructor(private venueService: VenueserviceService) { }

  panelOpenState = false;
  title = 'Cotswolds Destinations';

  venues: any = (data as any).default;

  categories: any = (catdata as any).default;

  formatLabel(value: number) {
    if (value >= 1000) {
      return Math.round(value / 1000) + 'm';
    }

    return value;
  }

  value = 'Clear me!';

  ngOnInit(): void {
    console.log("Homepage Start");
    console.log(this.categories);
    console.log(this.venues);
    console.log(data);
    console.log(this.venues.name);
    for(var i=0; i < this.venues.length; i++){
    console.log(this.venues[i]);
    }
    console.log("Homepage End");
    let categories = this.venueService.httpGetFeatures()

    console.log(categories)

  }
}



const getData =  async () => {
  const data  = await this.venueService.httpGetFeatures()
  console.log(data)
}

What I'd suggest is you do this

Service File

    httpGetFeatures() {
        console.log("inFeatures")
        return this.http.post("http://cotswoldsdestinations.co.uk:8443",
        {
            "command": "get_feature",
            "classes":"F,G"
        })
    }

Component File

fetchedData:any;
const getData =  async () => {
  this.venueService.httpGetFeatures()
    .subscribe( data => { this.fetchedData = data });
}

1st, you haven't returned anything in VenueserviceService.httpGetFeatures, it's return type is void.

2nd, you are expecting a promise in your getData lambda function, as you are using asyc-await syntax. Either do this:

httpGetFeatures() {
  return this.http.post("http://cotswoldsdestinations.co.uk:8443",
  {
    "command": "get_feature",
    "classes":"F,G"
  }).toPromise();
}

Or just subscribe to returned observable without awaiting:

httpGetFeatures() {
  return this.http.post("http://cotswoldsdestinations.co.uk:8443",
  {
    "command": "get_feature",
    "classes":"F,G"
  });
}
const getData = () => {
  this.venueService.httpGetFeatures().subscribe(data =>
    console.log(data);
  );
}

This is all ok if you defined getData within some component that has venueService: VenueserviceService passed via DI in it's constructor.

For it to work properly, define getData as a member of Home page component's class, eg:

export component HomePageComponent {
  constructor(private venueService: VenueserviceService) {}

  getData() {
    this.venueService.httpGetFeatures().subscribe(data =>
      console.log(data);
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM