Почему в View.showComponents передается undefined из класса с fetch?

Рейтинг: 1Ответов: 1Опубликовано: 10.03.2023

Есть контроллер, который получает преобразованный результат запроса кастомного класса FileRequest и передает его в метод класса View, который отрисовывает компоненты. Почему-то в renderComponents консоль-лог из конструктора класса, вызываемый в reponse (new FileRequest), происходит позже, чем консоль-лог перед View.showComponents. Почему же так происходит?

введите сюда описание изображения

import View from "@/pages/app/View";
import FileRequest from "@/Requests/FileRequest";

export default class AppController {
    static renderComponents() {
        let response = new Promise (function (resolve, reject) {
            resolve (new FileRequest('http://localhost:3000', FileRequest.parseToComponents));
        })
        response.then(results => {
            console.log(Object.keys(results));
            View.showComponents(results.results);
        })
    }
}

export default class View {
    static showComponents(response) {
        response.results.forEach(component => {
            document.querySelector('.page__files').append(component.DOM_LINK);
        })
    }
}

import {FileComponent} from "@components/file/File";
export default class FileRequest {
    constructor(url, callback) {
        fetch(url)
            .then((response) => {
                return response.json();
            })
            .then((results) => {
                this.results = callback(results.results);
                console.log(this.results);
            });
    }
    static parseToComponents(files) {
        let components = [];
        files.forEach(file => {
            components.push(new FileComponent(file));
        })
        return components;
    }
}

class File {
    constructor(file) {
        for (let key in file) {
            if (key !== 'id' && key !== 'identificator') {
                this[key] = file[key];
            }
        }
    }
}

export class FileComponent extends File {
    constructor(file) {
        super(file);

        Object.defineProperty(this, 'DOM_LINK', {
            value: document.createElement('div'),
            enumerable: false,
            configurable: false,
        });

        this.DOM_LINK.className = 'file';

        for (let key in this) {
            let element = document.createElement('p');
            element.className = `file__${key}`;
            element.textContent = `${key}: ${file[key]}`;
            this.DOM_LINK.append(element);
        }
    }
}

Ответы

▲ 1

Вот так должны выглядеть ваш классы. Добавляем работу с асинхронными методами

export default class AppController {
  static renderComponents() {
    // Создаем экземпляр класса
    const resp = new FileRequest('http://localhost:3000', FileRequest.parseToComponents);
    // Вызываем метод загрузки данных и после окончания передаем данные в View.showComponents
    resp.dataLoad().then(results => {
      console.log(Object.keys(results));
      View.showComponents(results.results);
    })
  }
}

export default class FileRequest {
  // Сохраняем значения
  constructor(url, callback) {
    this.url = url;
    this.callBack = callback;
  }
  // Загружаем данные
  async dataLoad() {
    return await fetch(this.url)
      .then((response) => {
        return response.json();
      })
      .then((results) => {
        console.log(this.results);
        // Сохраняем
        this.results = this.callBack(results.results);
        // Возвращаем
        return this.results;
      });
  }
  static parseToComponents(files) {
    let components = [];
    files.forEach(file => {
      components.push(new FileComponent(file));
    })
    return components;
  }
}