Получить запрос с помощью цикла - PullRequest
0 голосов
/ 03 февраля 2019

Была такая проблема.

Я пытаюсь выполнить определенное количество запросов GET в API Википедии, используя цикл.Попытка сделать это с помощью функции getAllInfo()

article.components.ts

export class ArticlesComponent {
  constructor(private articlesServices: ArticlesService) { }

  @Input() allTitles: string[];

  articlesInfo: ArticleInformationNew;
  allArray: [[string, number]] = [['', 0]];

  static getUrlInformation(searchQuery: string) {
    return 'https://ru.wikipedia.org/w/api.php?action=query&titles='
      + searchQuery + '&prop=info&format=json&origin=*';
  }

  getAllInfo() {
    for (const title of this.allTitles) {
      this.articlesServices.getArticleInformation(ArticlesComponent.getUrlInformation(title))
        .subscribe(
          (data: ArticleInformation) => this.articlesInfo = {
            ...data,
            query: { pages: [Object.values(data.query.pages)[0]]}}
        );
        this.allArray.push([this.articlesInfo.query.pages[0].touched, this.articlesInfo.query.pages[0].length]);
    }
  }
}

article.service.ts

export interface ArticleInformation {
  batchComplete: string;
  query: {
    pages: {
    }
  };
}

export interface ArticleInformationNew {
  batchComplete: string;
  query: {
    pages: any[]
  };
}

export class ArticlesService {
  constructor(private http: HttpClient) { }

  getArticleInformation(url) {
    return this.http.get<ArticleInformation>(url);
  }
}

Массив this.allTitles может состоять из нескольких строк. Например, : this.allTitles = ['Naumen', 'Naumen DMS']

Я ожидаю, что массив this.allArray будет двухмерным и будет содержать массивы, состоящие из строк с данными для каждого запроса. Например, :

this.allArray[0] = ['', 0]
this.allArray[1] = ['2019-02-01T23:27:26Z', 3687]
this.allArray[2] = ['2019-01-21T04:24:21Z', 9704]

Но на самом деле оказывается, что каждый элемент двумерного массива одинаков. Например :

this.allArray[0] = ['', 0]
this.allArray[1] = ['2019-02-01T23:27:26Z', 3687]
this.allArray[2] = ['2019-02-01T23:27:26Z', 3687]

Почему и как это исправить?

Ответы [ 3 ]

0 голосов
/ 03 февраля 2019

Может быть, я неправильно понял вопрос, но вы можете получить страницы с определенными заголовками, исправив searchQuery (используя альтернативные разделители для заголовков), и избавиться от for loop:

getAllInfo() {
  console.log(this.allTitles);

 this.articlesServices.getArticleInformation(
   ArticlesComponent.getUrlInformation(this.allTitles.join('|'))
     .subscribe(
       (res => {
         // here is a result with all pages of particular titles,
         // then you can process your result...
         console.log(res);

         // this.allArray is a multidimensional array
         // [["2019-01-25T00:45:06Z",4508],
         // ["2019-01-26T07:25:08Z", 773]]
         this.allArray = Object.keys(res.query.pages)
           .reduce((acc, val, index) => {
             acc[index] = [pages[val].touched, pages[val].length];
             return acc;
           }, []);
     });
}

searchQuery для заголовков будет в этом случае Naumen | Naumen DMS (не, например, просто Naumen).|(pipe) является альтернативным разделителем для заголовков.

Для обработки результата (res.query.pages):

const pages = {
  "755288": {
    "pageid": 755288,
    "ns": 0,
    "title": "Spring",
    "contentmodel": "wikitext",
    "pagelanguage": "ru",
    "pagelanguagehtmlcode": "ru",
    "pagelanguagedir": "ltr",
    "touched": "2019-01-26T07:25:08Z",
    "lastrevid": 84434967,
    "length": 773
  },
  "92586": {
    "pageid": 92586,
    "ns": 0,
    "title": "Atom",
    "contentmodel": "wikitext",
    "pagelanguage": "ru",
    "pagelanguagehtmlcode": "ru",
    "pagelanguagedir": "ltr",
    "touched": "2019-01-25T00:45:06Z",
    "lastrevid": 95248014,
    "length": 4508
  },
};
 
const arr = Object.keys(pages).reduce((acc, val, index) => {
  acc[index] = [pages[val].touched, pages[val].length];
  return acc;
}, []);

console.log(arr);
0 голосов
/ 03 февраля 2019

Попробуйте,

getAllInfo() {
    for (const title of this.allTitles) {
      this.articlesServices.getArticleInformation(ArticlesComponent.getUrlInformation(title))
        .subscribe(
          (data: ArticleInformation) => {
            this.articlesInfo = {
                ...data,
                query: { pages: [Object.values(data.query.pages)[0]]}
            }
            this.allArray.push([this.articlesInfo.query.pages[0].touched,this.articlesInfo.query.pages[0].length]);
          } 
        );

    }
  }
0 голосов
/ 03 февраля 2019

Вы можете использовать combineLatest: https://www.learnrxjs.io/operators/combination/combinelatest.html

Сначала соберите наблюдаемые объекты для объединения (но не подписываясь на них), затем объедините их с combineLatest и получите ответ как arrayи перебрать его.

getAllInfo() {
    console.log(this.allTitles);

    observablesToSubscribe = [];

    for (const title of this.allTitles) {
      observablesToSubscribe.push(this.articlesServices.getArticleInformation(ArticlesComponent.getUrlInformation(title)));
    }

   combineLatest(observablesToSubscribe).subscribe((responseData: Array<ArticleInformation>) => {
       responseData.forEach((responseDatum) => {
           this.allArray.push({
              ...data,
              query: { pages: [Object.values(data.query.pages)[0]]}
           })
       });   
   });     
}
...