Загрузите локальную JSON-асинхронную службу httpclient в Angular. - PullRequest
1 голос
/ 18 мая 2019

Я пытаюсь вызвать загрузку Json с сервисом Angular не по ngOnInit, а по кнопке по запросу пользователя. Это швы, это действительно загружает это, но не делает это асинхронно. Я получаю эту ошибку: Ошибка ОШИБКА: Uncaught (в обещании): Ошибка типа:

Я новичок в Angular, поэтому не судите.

core.js:15724 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'length' of undefined
TypeError: Cannot read property 'length' of undefined
    at PollComponent.push../src/app/components/poll/poll.component.ts.PollComponent.shuffle (poll.component.ts:23)
    at PollComponent.<anonymous> (poll.component.ts:44)
    at step (tslib.es6.js:97)
    at Object.next (tslib.es6.js:78)
    at fulfilled (tslib.es6.js:68)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)
    at Object.onInvoke (core.js:17299)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:390)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:150)
    at zone.js:889
    at resolvePromise (zone.js:831)
    at zone.js:741
    at fulfilled (tslib.es6.js:68)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)
    at Object.onInvoke (core.js:17299)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:390)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:150)
    at zone.js:889
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:17290)
defaultErrorLogger @ core.js:15724
push../node_modules/@angular/core/fesm5/core.js.ErrorHandler.handleError @ core.js:15772
next @ core.js:17771
schedulerFn @ core.js:13515
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub @ Subscriber.js:196
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next @ Subscriber.js:134
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next @ Subscriber.js:77
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:54
push../node_modules/rxjs/_esm5/internal/Subject.js.Subject.next @ Subject.js:47
push../node_modules/@angular/core/fesm5/core.js.EventEmitter.emit @ core.js:13499
(anonymous) @ core.js:17321
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:391
push../node_modules/zone.js/dist/zone.js.Zone.run @ zone.js:150
push../node_modules/@angular/core/fesm5/core.js.NgZone.runOutsideAngular @ core.js:17258
onHandleError @ core.js:17321
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.handleError @ zone.js:395
push../node_modules/zone.js/dist/zone.js.Zone.runGuarded @ zone.js:164
_loop_1 @ zone.js:694
api.microtaskDrainDone @ zone.js:703
drainMicroTaskQueue @ zone.js:608
push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:502
invokeTask @ zone.js:1744
globalZoneAwareCallback @ zone.js:1770

Вот мой сервис:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { IQuestion } from '../../assets/IData';

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

  private _url: string = "assets/data/TEST_me_50_Pyetje.json";
  constructor(private http: HttpClient) {

   }

  getQuestions() : Observable<IQuestion[]> {
    return this.http.get<IQuestion[]>(this._url);
   }
}

и вот мой метод. Он вызывается кнопкой в ​​HTML:

  ngOnInit() {

  }
  async startTestClick(){

      var promise = await this.pollService.getQuestions().subscribe(data => this.que = data);
      this.nrSakte = 0;
      this.testQuestions = this.shuffle(this.que).slice(0,50);
      for (let entry of this.testQuestions) {
        entry.picture ="A";
        entry.color = "black";
      }


      let a = await document.getElementsByClassName("alternativa");
      for(let j in a){
        a[j].setAttribute("style", "background-color:#fafafa;");
      }
  }

Я действительно хочу дождаться загрузки всего Json, чтобы я мог выбирать, какие элементы отображать в HTML. Он показывает их, но показывает эти ошибки. Если я хочу динамически загрузить какой-нибудь другой json, он больше не работает.

Заранее спасибо!

1 Ответ

0 голосов
/ 19 мая 2019

Я думаю, вам нужно переместить некоторую логику внутри subscribe в вашем вызове на startTestClick.

Как-то так:

async startTestClick() {

    var promise = await this.pollService.getQuestions().subscribe(data => {
        this.que = data;
        this.nrSakte = 0;
        this.testQuestions = this.shuffle(this.que).slice(0,50);
        for (let entry of this.testQuestions) {
            entry.picture ="A";
            entry.color = "black";
        }
    });
    ...
}

Без этого остальные вашикод будет выполняться, пока subscribe ожидает результатов, а this.que еще ничего не имеет.

Не думаю, что вам действительно нужен async/await.Так что это тоже может сработать.

startTestClick() {

    this.pollService.getQuestions().subscribe(data => {
        this.que = data;
        this.nrSakte = 0;
        this.testQuestions = this.shuffle(this.que).slice(0,50);
        for (let entry of this.testQuestions) {
            entry.picture ="A";
            entry.color = "black";
        }
    });
    ...
}

Опять же, вы используете await для вызова document.getElementsByClassName, так что я могу ошибаться.Возможно, этот вызов должен быть и внутри subscribe.

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

...