Angular / Typescript - Выполнение вызова метода в операторе возврата обещания - PullRequest
0 голосов
/ 17 января 2020

Я создал компонент в Angular, который читает файл XML и использует синтаксический анализатор для его отображения в таблице HTML, которая есть у компонента. В методе синтаксического анализа я хочу изменить функциональность отображаемых данных, изменив определенные аспекты, когда они достигаются в прочитанных данных XML, но всякий раз, когда я пытаюсь вызвать метод, который вернет измененные данные, которые я получаю ошибка с указанием:

"core. js: 15724 Ошибка ОШИБКИ: Uncaught (в обещании): TypeError: Невозможно прочитать свойство 'CurrencyConvChange' из неопределенного TypeError: Невозможно прочитать свойство 'CurrencyConvChange' из неопределенного".

Это код для машинописного файла моего основного компонента:

import { Component, OnInit } from '@angular/core';
import * as xml2js from 'xml2js';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { DataStoreService } from '../../data-store.service';

@Component
({
  selector: 'app-tableofshares',
  templateUrl: './tableofshares.component.html',
  styleUrls: ['./tableofshares.component.css']
})

export class TableofsharesComponent
{
  public xmlItems: any;
  new_curr_value;
  test_1 = 1;
  test_2 = 1;

  constructor(private http: HttpClient, private store: DataStoreService)
  // tslint:disable-next-line: one-line
  {
    this.loadXML(); // Runs below function when the project is started.
  }

  async CurrencyConvChange(test_1, test_2)
  {
    console.dir("recieved test 1: " + test_1);
    console.dir("recieved test 2: " + test_2);
    return 0;
  }

  // Loads the data
  loadXML()
  {
    this.http.get('assets/Shares_Data.xml',
    {
      headers: new HttpHeaders()
      .set('Content-Type', 'text/xml')
      .append('Access-Control-Allow-Methods', 'GET')
      .append('Access-Control-Allow-Origin', '*')
      // tslint:disable-next-line: max-line-length
      .append('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers, Access-Control-Allow-Origin, Access-Control-Request-Method'),
      responseType: 'text'
    }).subscribe((data) => {
      this.parseXML(data).then((data) =>
      {
        this.xmlItems = data; // Assigns xmlItems data from request
      });
    });
  }

  // Manipulates the data
  async parseXML(data)
  {
    return new Promise(resolve =>
    {
      let k: string | number,
      arr = [],
      test_var,
      parser = new xml2js.Parser({trim: true, explicitArray: true});

      parser.parseString(data, function(err, result)
      {
        const obj = result.ShareList;
        // tslint:disable-next-line: forin
        for (k in obj.share)
        {
          const item = obj.share[k];
          const test_1 = item.sharePrice[0].currency[0];
          console.dir("test 1: " + test_1);

          const test_2 = item.sharePrice[0].value[0];
          console.dir("Test 2: " + test_2);

          this.CurrencyConvChange(test_1, test_2);

          arr.push
          ({
            title: item.title[0], companySymbol: item.companySymbol[0],
            numOfShares: item.numOfShares[0], lastShareUpdate: item.lastShareUpdate[0],
            currency: item.sharePrice[0].currency, value: item.sharePrice[0].value
          });
        }
        resolve(arr);
      });
    });
  }
}

Я вызываю нужный метод в строке "this.CurrencyConvChange (test_1, test_2)" и am сбит с толку полученной ошибкой, поскольку я уже определил метод CurrencyConvChange перед любым другим. Я несколько новичок в машинописи и мне было интересно, было ли это какое-то правило, о котором я раньше не знал?

Ответы [ 2 ]

4 голосов
/ 17 января 2020

Это не связано ни с машинописью, ни с обещаниями. Это связано со ссылкой this.

Вы определяете функцию обратного вызова

 parser.parseString(data, function(err, result)

Внутри этой функции вы пытаетесь получить доступ к this

 this.CurrencyConvChange

Но внутри этой функции this относится к определенной вами функции обратного вызова. Не для вашего экземпляра компонента. Если вы хотите указать правильный this, используйте функцию стрелки для определения вашего обратного вызова, как показано ниже:

 parser.parseString(data, (err, result) => ....

Или используйте более уродливый обходной путь, как показано ниже:

let that = this; // outside of function
// inside your function
that.CurrencyConvChange 
0 голосов
/ 17 января 2020

У меня есть глупое исправление, которое часто используют. В вашем классе объявите:

static _this: any;

В вашем конструкторе присвойте:

TableofsharesComponent._this = this;

Тогда вы можете вызвать вашу функцию следующим образом:

TableofsharesComponent._this.CurrencyConvChange(test_1, test_2). 

Если это плохая идея, я хотел бы услышать почему, чтобы я мог исправить свой код.

...