How to handle a two-dimensional array using ngFor? I receive here such array
As a result, I need to get the blocks in which the data from the array is displayed in order. That is, in the case of an array that is represented on the screen, there would be 10 blocks. Example:
<div>
<span>Yandex</span>
<span>Yandex.N.V....</span>
<span>;/span>
</div>
<div>
<span>Yandex Browser</span>
<span>IPA:...</span>
<span>;/span>
</div>
etc.
I do it that way.
<h3>Get Articles</h3>
<div>
<div *ngIf="articles">
<div *ngFor="let article of articles">
<span>{{ article[1] }}</span>
<span>{{ article[2] }}</span>
<span>{{ article[3] }}</span>
</div>
</div>
</div>
I understand that this is wrong, but I can not find my stupid mistake. The output is either an error or a strange conclusion.
searchponent.ts
import { Component, OnInit } from '@angular/core';
import { Article, ArticlesService } from '../../services/articles.service';
@Component({
selector: 'app-search',
templateUrl: './searchponent.html',
styleUrls: ['./searchponent.css'],
providers: [ArticlesService]
})
export class SearchComponent implements OnInit {
constructor(private articlesServices: ArticlesService) { }
searchQuery: string;
limit: number;
error: any;
articles: { };
// noinspection JSMethodCanBeStatic
getUrl(searchQuery: string) {
return '.php?action=opensearch&search='
+ searchQuery + '&limit=10&namespace=0&format=json&origin=*';
}
showArticles() {
this.articlesServices.getArticles(this.getUrl(this.searchQuery))
.subscribe(
(data: Article) => this.articles = Object.values({
title: data[0],
collection: data[1],
description: data[2],
links: data[3]
}),
error => this.error = error
);
console.log(this.articles);
}
ngOnInit() {
}
}
articleponent.ts
import { Component, OnInit, Input } from '@angular/core';
import {Article, ArticleInfo, ArticlesService} from '../../services/articles.service';
@Component({
selector: 'app-articles',
templateUrl: './articlesponent.html',
styleUrls: ['./articlesponent.css'],
})
export class ArticlesComponent implements OnInit {
@Input() articles: Article;
@Input() searchQuery: string;
constructor(private articlesServices: ArticlesService) { }
information: ArticleInfo;
getUrl(searchQuery: string) {
return '.php?action=query&list=search&srsearch=' +
searchQuery + '&utf8=&format=json&origin=*';
}
showArticlesInformation() {
this.articlesServices.getArticlesInfo(this.getUrl(this.searchQuery))
.subscribe(
(data: ArticleInfo) => this.information = {
query: data.query.search
}
);
console.log(this.information);
}
ngOnInit() {
}
}
article.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/mon/http';
import { throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';
export interface Article {
title: string;
collection: string[];
description: string[];
links: string[];
}
export interface ArticleInfo {
query: {
search
};
}
@Injectable({
providedIn: 'root'
})
export class ArticlesService {
constructor(private http: HttpClient) { }
getArticles(url) {
return this.http.get(url)
.pipe(
retry(3),
catchError(this.handleError)
);
}
getArticlesInfo(url) {
return this.http.get<ArticleInfo>(url);
}
// noinspection JSMethodCanBeStatic
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.error('An error occurred:', error.error.message);
} else {
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
return throwError(
'Something bad happened; please try again later.');
}
}
Come 2D array
Then it should turn out like this
How to handle a two-dimensional array using ngFor? I receive here such array
As a result, I need to get the blocks in which the data from the array is displayed in order. That is, in the case of an array that is represented on the screen, there would be 10 blocks. Example:
<div>
<span>Yandex</span>
<span>Yandex.N.V....</span>
<span>https://en.wikipedia/wiki/Yandex</span>
</div>
<div>
<span>Yandex Browser</span>
<span>IPA:...</span>
<span>https://en.wikipedia/wiki/Yandex_Browser</span>
</div>
etc.
I do it that way.
<h3>Get Articles</h3>
<div>
<div *ngIf="articles">
<div *ngFor="let article of articles">
<span>{{ article[1] }}</span>
<span>{{ article[2] }}</span>
<span>{{ article[3] }}</span>
</div>
</div>
</div>
I understand that this is wrong, but I can not find my stupid mistake. The output is either an error or a strange conclusion.
search.ponent.ts
import { Component, OnInit } from '@angular/core';
import { Article, ArticlesService } from '../../services/articles.service';
@Component({
selector: 'app-search',
templateUrl: './search.ponent.html',
styleUrls: ['./search.ponent.css'],
providers: [ArticlesService]
})
export class SearchComponent implements OnInit {
constructor(private articlesServices: ArticlesService) { }
searchQuery: string;
limit: number;
error: any;
articles: { };
// noinspection JSMethodCanBeStatic
getUrl(searchQuery: string) {
return 'https://en.wikipedia/w/api.php?action=opensearch&search='
+ searchQuery + '&limit=10&namespace=0&format=json&origin=*';
}
showArticles() {
this.articlesServices.getArticles(this.getUrl(this.searchQuery))
.subscribe(
(data: Article) => this.articles = Object.values({
title: data[0],
collection: data[1],
description: data[2],
links: data[3]
}),
error => this.error = error
);
console.log(this.articles);
}
ngOnInit() {
}
}
article.ponent.ts
import { Component, OnInit, Input } from '@angular/core';
import {Article, ArticleInfo, ArticlesService} from '../../services/articles.service';
@Component({
selector: 'app-articles',
templateUrl: './articles.ponent.html',
styleUrls: ['./articles.ponent.css'],
})
export class ArticlesComponent implements OnInit {
@Input() articles: Article;
@Input() searchQuery: string;
constructor(private articlesServices: ArticlesService) { }
information: ArticleInfo;
getUrl(searchQuery: string) {
return 'https://ru.wikipedia/w/api.php?action=query&list=search&srsearch=' +
searchQuery + '&utf8=&format=json&origin=*';
}
showArticlesInformation() {
this.articlesServices.getArticlesInfo(this.getUrl(this.searchQuery))
.subscribe(
(data: ArticleInfo) => this.information = {
query: data.query.search
}
);
console.log(this.information);
}
ngOnInit() {
}
}
article.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/mon/http';
import { throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';
export interface Article {
title: string;
collection: string[];
description: string[];
links: string[];
}
export interface ArticleInfo {
query: {
search
};
}
@Injectable({
providedIn: 'root'
})
export class ArticlesService {
constructor(private http: HttpClient) { }
getArticles(url) {
return this.http.get(url)
.pipe(
retry(3),
catchError(this.handleError)
);
}
getArticlesInfo(url) {
return this.http.get<ArticleInfo>(url);
}
// noinspection JSMethodCanBeStatic
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.error('An error occurred:', error.error.message);
} else {
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
return throwError(
'Something bad happened; please try again later.');
}
}
Come 2D array
Then it should turn out like this
Share Improve this question edited Feb 1, 2019 at 11:10 asked Feb 1, 2019 at 9:33 user10990607user10990607 5-
Is
articles
your 2D array? – MonkeyScript Commented Feb 1, 2019 at 10:32 -
Yes.
articles: [string, string[], string[], string[]
– user10990607 Commented Feb 1, 2019 at 10:33 - Tried nested loops? – MonkeyScript Commented Feb 1, 2019 at 10:34
-
Yes. If you use this, there will be an error.
<div *ngFor="let article of articles"><div *ngFor=let collection of article[1]>{{ collection }}</div></div>
– user10990607 Commented Feb 1, 2019 at 10:37 - There is syntax mistake in that. I've given an answer below. – MonkeyScript Commented Feb 1, 2019 at 10:40
2 Answers
Reset to default 3Try this,
<div>
{{articles[0]}}
</div>
<div *ngFor="let article of articles[1]; let i=index">
<span>
{{article}}
</span>
<span *ngFor="let info1 of articles[2]; let j=index" [hidden]="i!=j">
{{info1}}
</span>
<span *ngFor="let info2 of articles[3]; let k=index" [hidden]="i!=k">
{{info2}}
</span>
</div>
Try storing the result into Observable and into the html file use async pipe.
<div *ngFor="let article of articles | async">
In your search.ponent.ts
articles : Observable<Article>;
...
this.articles = this.articlesServices.getArticles(this.getUrl(this.searchQuery)).catch(error => this.error = error );