невозможно назначить данные из данных ответа в Angular - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть функция, которая должна вызывать массив объектов при вызове. Функция выглядит следующим образом

loadTodo(): Todo[]{
var data 
this.http.get(`${this.API_URL}todos`).toPromise().then(res => {
  data = res.json()
  }, error => {
    console.log(error)
  })
  return data}

Это приводит к неожиданному поведению, когда переменная data назначается правильно в блоке ответа об успешном выполнении, но имеет значение undefined при доступе вне блока ответа.

Функция присваивается переменной с типом Todo[] и вызывается сразу после объявления переменной. Я совершенно новичок в TypeScript и Angular, но не в JavaScript. Я что-то упускаю из-за области действия / закрытия функции или эта проблема связана с TypeScript / Angular?

Весь класс выглядит так:

export class TodoDataService {
  API_URL: String = 'http://localhost:3000/'  
  todos: Todo[] = this.loadTodo();
  constructor(private http: Http) {
  }
  loadTodo(): Todo[]{
    this.http.get(`${this.API_URL}todos`).toPromise().then(res => {
      this.parcedTodos = res.json()
      console.log('inside function')
      console.log(this.parcedTodos)
      }, error => {
        console.log(error)
      })
      console.log('outside function')
      console.log(this.parcedTodos)
      return this.parcedTodos
  }
}

Ответы [ 4 ]

0 голосов
/ 27 апреля 2018

this.http.get(whatever) - это вызов async. Ваш data равен undefined, потому что вы обращаетесь к нему до его инициализации. то есть вы инициализируете его внутри обработчика success (первый аргумент then) и, вероятно, обращаетесь к нему до инициализации.

Все, что вам нужно сделать, это убедиться, что вы делаете это после обработчика success или error. используйте Observable

0 голосов
/ 27 апреля 2018

http.get() является асинхронным, что означает, что при попытке вывести parcedTodos за пределами обратного вызова then оно все равно будет неопределенным.

Асинхронное программирование в JS

0 голосов
/ 27 апреля 2018

Это происходит потому, что http звонки asynchronous.

Вам необходимо убедиться, что вы получаете доступ к данным только после завершения вызова.

export class TodoDataService {
  API_URL: String = 'http://localhost:3000/'  
  todos: Todo[] = this.loadTodo();
  constructor(private http: Http) {
  }
  loadTodo(): Todo[]{
    this.http.get(`${this.API_URL}todos`).toPromise().then(res => {
      this.parcedTodos = res.json()
      console.log('inside function')
      console.log(this.parcedTodos)
      }, error => {
        console.log(error)
      },
      {
        console.log(this.parcedTodos);
        // This is where your call gets completed. Here you can access assigned data or call another function where you can access data.
      })
      console.log('outside function')
      console.log(this.parcedTodos) // This is called before asynchronous call is completed. Thats why it is undefined yet.
      return this.parcedTodos
  }
}

Надеюсь, это поможет.

0 голосов
/ 27 апреля 2018

Я думаю, что использование res.json() не является необходимым, потому что угловые трубы уже делают это. Вы пытаетесь присвоить переменной res напрямую?

Как говорят другие друзья, ты делаешь что-то плохое.

Первое: вы должны прочитать об асинхронных методах

Второе: используйте Observables, импортирующие rxjs / Observable; и следовать его обратным вызовам

Пример

    export class TodoDataService {
  API_URL: String = 'http://localhost:3000/'  
  todos: Todo[] = this.loadTodo();
  constructor(private http: Http) {
  }
  loadTodo() : Observable<Todo[]>{
    return this.http.get(`${this.API_URL}todos`);
  }
}

И другой класс потребляет этот метод

 todoDataService.loadTodo().subscribe(
        (response) => {
          console.log("Future response", response);
        }
    );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...