Reputation: 1147
I'm very new to Angular and currently I'm learning Angular 6, which is the latest version of Angular.
Here, I'm trying to design my blog page with articles which are retrieved from a JSON and displaying them in 2 columns, as in picture below:
The number next to title are index of article in array of articles. It's easily to see the problem: indexes from 1 are duplicated twice.
This is my code, please show me why I'm wrong in details and how can I fix that.
BlogService:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class BlogService {
constructor(private http: HttpClient) { }
getArticleList() {
return this.http.get('https://jsonplaceholder.typicode.com/posts');
}
}
ArticleListComponent:
import { Component, OnInit } from '@angular/core'; import { BlogService } from '../blog.service';
@Component({
selector: 'app-blog',
templateUrl: './article-list.component.html',
styleUrls: ['./article-list.component.css']
})
export class ArticleListComponent implements OnInit {
articles: Object;
constructor(private data: BlogService) { }
ngOnInit() {
this.data.getArticleList().subscribe(
data => this.articles = data
);
}
}
HTML file:
<div class="article-list-page">
<div class="container">
<h3>This is blog page</h3>
<p>The industry's top wizards, doctors, and other experts offer their best advice, research, how-tos,
and insights, all in the name of helping you level-up your SEO and online marketing skills. Looking for the YouMoz Blog? </p>
<span *ngFor="let index of articles; index as i">
<div style="display: table; border: 1px solid black">
<div class="posts-left col-md-6" style="display: table-row;">
<a>{{ articles[i].title }} -- {{i}}</a>
<p>{{ articles[i].body }}</p>
</div>
<div class="posts-right col-md-6" style="display: table-row;">
<a>{{ articles[i + 1].title }} -- {{i + 1}}</a>
<p>{{ articles[i + 1].body }}</p>
</div>
</div>
</span>
</div>
</div>
Upvotes: 7
Views: 30796
Reputation: 5045
Instead of using a table and trying to apply indexes that way, you will be better off using CSS. For example:
In my component.ts:
numArray=[100,200,300,400,500,600,700,800];
In my view:
<ul>
<li *ngFor="let n of numArray; index as i">{{n}}, Index is {{i}}</li>
</ul>
In the css:
ul{
width:400px;
}
li{
float: left;
list-style: none;
width:150px;
margin: 0px;
}
li:nth-child(even){
margin-right: 0px;
}
This will give the output as:
You can modify the example I have given to suit your needs.
Upvotes: 14
Reputation: 17848
TL;DR; Just replace this block in your HTML file
From:
<div style="display: table; border: 1px solid black">
<div class="posts-left col-md-6" style="display: table-row;">
<a>{{ articles[i].title }} -- {{i}}</a>
<p>{{ articles[i].body }}</p>
</div>
<div class="posts-right col-md-6" style="display: table-row;">
<a>{{ articles[i + 1].title }} -- {{i + 1}}</a>
<p>{{ articles[i + 1].body }}</p>
</div>
</div>
To: (removed 4 lines)
<div style="display: table; border: 1px solid black">
<div class="posts-left col-md-6" style="display: table-row;">
<a>{{ articles[i].title }} -- {{i}}</a>
<p>{{ articles[i].body }}</p>
</div>
</div>
From your screenshot, it appears that only the 0th
element that is not repeated twice. And based on your HTML, this is expected since you're rendering it twice.
Your current template
<span *ngFor="let index of articles; index as i">
<div style="display: table; border: 1px solid black">
<div class="posts-left col-md-6" style="display: table-row;">
<!-- 1. Render the CURRENT 'article' -->
<a>{{ articles[i].title }} -- {{i}}</a>
<p>{{ articles[i].body }}</p>
</div>
<div class="posts-right col-md-6" style="display: table-row;">
<!-- 2. Render the NEXT 'article' -->
<a>{{ articles[i + 1].title }} -- {{i + 1}}</a>
<p>{{ articles[i + 1].body }}</p>
</div>
</div>
</span>
Following is the steps of how angular renders your articles
.
If you just want to render once per element, simply do it like,
<div class="posts-left col-md-6" style="display: table-row;">
<!-- 1. Render ONLY THE CURRENT 'article' -->
<a>{{ articles[i].title }} -- {{i}}</a>
<p>{{ articles[i].body }}</p>
</div>
Note: There is already a post who makes a good use of ngFor
HERE.
Upvotes: 1
Reputation: 21628
Create an array of the even indexes
this.indexes = data.reduce((indexes, _, i) => i % 2 ? indexes : [...indexes, i], []);
And in your view you can ngFor on just the even indexes
<span *ngFor="let index of indexes">
Upvotes: 0