I will appreciate any ideas and support for this issue
I have an angular project and I try to create icons share buttons for social media.
I have a component named landing.component. in the HTML file I implemented a Modal popup to allow showing a new windows where I have the icons. Please, follow screenshots below
Below, is the new windows
the HTML code is here
<div class="card-wrapper" fxLayout="row wrap" fxLayoutAlign="start start">
<div
class="card active-card"
fxFlex="25"
*ngFor="let category of categories"
(click)="categoryClick(category)"
>
<picture>
<img [src]="category.imageLocation" />
</picture>
<div class="card-overlay" fxLayout="row wrap" fxLayoutAlign="center end">
<span class="card-title" fxFlex="100">{{ category.title }}</span>
<div class="card-buttons" fxFlex="100" fxLayout="row">
<ul class="list-inline text-center member-icons ">
<li class="list-inline-item">
<button mat-icon-button disableRipple class="btn btn-primary" routerLink="/mtl" (click)="open(content)"><i class="fa-solid fa-share"></i></button>
</li>
<span fxFlex></span>
</ul>
<!-- <button mat-icon-button disableRipple>
<heart-icon></heart-icon>
</button> -->
<!-- <span fxFlex></span> -->
<!-- <button mat-icon-button disableRipple> -->
<!-- <download-icon></download-icon> -->
<!-- </button> -->
<!-- <button mat-icon-button disableRipple>
<share-icon></share-icon>
</button> -->
</div>
</div>
</div>
</div>
<section
class="cragcity-container p-t-5"
fxLayout="row"
fxLayoutAlign="space-between start"
>
<div style="margin: auto">
<img class="socmed-icon m-r-15" src="./assets/icons/facebook.webp" />
<img class="socmed-icon m-r-15" src="./assets/icons/skype.webp" />
<img class="socmed-icon" src="./assets/icons/instagram.webp" />
</div>
</section>
<ng-template #content let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Share Social Media</h4>
<button type="button" class="btn-close" aria-label="Close" (click)="modal.dismiss('Cross click')"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label for="Social Media"></label>
<div class="share-btn-container">
<a #facebook href="#" class="facebook-btn">
<i class="fab fa-facebook"></i>
</a>
<a href="#" class="twitter-btn">
<i class="fab fa-twitter"></i>
</a>
<a href="#" class="pinterest-btn">
<i class="fab fa-pinterest"></i>
</a>
<a href="#" class="linkedin-btn">
<i class="fab fa-linkedin"></i>
</a>
<a href="#" class="whatsapp-btn">
<i class="fab fa-whatsapp"></i>
</a>
</div>
<!-- <div class="input-group">
<input
name="dp"
ngbDatepicker
#dp="ngbDatepicker"
/>
<button class="btn btn-outline-secondary bi bi-calendar3" (click)="dp.toggle()" type="button"></button>
</div> -->
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="modal.close('Save click')">Close</button>
</div>
</ng-template>
<app-cragcity-footer></app-cragcity-footer>
In the facebook option, I created a variable #facebook that will allow me to use viewchildren in the ts file to do an elementref and find the element in the DOM.
In the viewchildren option, I created a variable link1.
then, in the ngAfterViewInit I created two variables url and title. the url variable will take the link of my page to be share and the title is just message.
Finally, I used this command:
this.link1.nativeElement.setAttribute("href",`https://www.facebook.com/sharer.php?u=${this.url}`)
(this is what I believe is the same in js document.location.href) but used in ts
The code is not working, basically when I click the facebook icon only close the windows and that's it and the web shows me this error here bbelwo:
the landing. component.ts code is here below:
import { Component, OnInit, Input, ViewChild, ElementRef, AfterViewInit, ViewChildren } from '#angular/core';
import { Router, ActivatedRoute } from '#angular/router';
import { DataService } from 'src/app/core/services/data.service';
import { category } from '../models/category';
import { ModalDismissReasons, NgbActiveModal, NgbModal } from '#ng-bootstrap/ng-bootstrap';
#Component({
selector: 'app-landing',
templateUrl: './landing.component.html',
styleUrls: ['./landing.component.scss']
})
export class LandingComponent implements OnInit, AfterViewInit {
public categories = new Array<category>();
#Input() name;
url:string;
title:string;
closeResult: string | undefined;
constructor(private _dataService: DataService, private router: Router, private modalService: NgbModal, private route: ActivatedRoute) {
}
ngOnInit(): void {
this.retrieveCategories();
}
#ViewChildren("facebook")link1: ElementRef;
ngAfterViewInit() {
this.url = this.router.url;
/* this.link1.nativeElement = this.url; */
this.title = encodeURI("Facebook");
this.link1.nativeElement.setAttribute("href",`https://www.facebook.com/sharer.php?u=${this.url}`)
/* console.log(this.link1);
console.log(this.url);
*/
/* this.link1.nativeElement.setAttribute('xlink:href') */
}
retrieveCategories() {
const actionUrl = 'v1/category';
const params = {};
this._dataService.get<any>(actionUrl, params)
.subscribe(data => {
if (data !== null) {
if (!data.isError) { this.categories = data.result; }
}
});
}
categoryClick(data: category) {
if (data.subCategory.length > 0)
this.router.navigate(['mtl', data.id]);
}
open(content) {
this.modalService.open(content, { ariaLabelledBy: 'modal-basic-title' }).result.then(
(result) => {
this.closeResult = `Closed with: ${result}`;
},
(reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
},
);
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return 'by pressing ESC';
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return 'by clicking on a backdrop';
} else {
return `with: ${reason}`;
}
}
}
I really appreciate any help
Regards
First it is a different between #ViewChild and #ViewChildren. The first will search one element, the second multiple elements. So in your case use #ViewChild("facebook") link1: any;
But a besser approach is to let Angular do this thing and don't use setAttribute to the native element. So you can bind anything to the href attribute like this:
HTML
<a #facebook [href]="facebookLink" class="facebook-btn">
<i class="fab fa-facebook"></i>
</a>
Code
facebookLink: string = "https://facebook.com";
You can generate the links with a ngFor loop, too for more flexibility.
CODE
linkObjects = [{iconClassI: "fab fa-facebook", iconClassA: "facebook-btn", link: "http://facebook.com"}, {... all other links}]
HTML
<div class="share-btn-container">
<a *ngFor="let item of linkObjects" [href]="item.link" [class]="item.iconClassA">
<i [class]="item.iconClassI"></i>
</a>
</div>
Related
I am using the ngx-pagination library for my angular app.
Besides the previous and next button I want to add 2 more buttons to go directly on the last page or on the first page.
How can I achieve this ?
Template logic
import { Component, OnInit } from '#angular/core';
import { TestimonialsDataService } from '../../services/testimonials-data.service';
#Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.scss']
})
export class CardComponent implements OnInit {
public authors: Object = {};
public pageList: number = 1;
constructor(private _testimonialsService: TestimonialsDataService) { }
ngOnInit(): void {
this._testimonialsService.getData().subscribe(data => this.authors = data);
}
}
<div class="container">
<div class="content">
<div class="card" *ngFor="let author of authors['user'] | paginate: {id: 'list-pagination', itemsPerPage: 9, currentPage: pageList}" >
<div class="card-content">
<img class="image" src="{{author.image}}"/>
<p class="author">{{author.name}}</p>
<p class="job">{{author.job}}</p>
<p class="company">{{author.company}}</p>
<p class="country"><span class="flag flag-IT"></span><span class="country">{{author.country}}</span></p>
</div>
</div>
</div>
<pagination-controls id="list-pagination" lastLabel="Next" class="list-pagination" directionLinks="true" (pageChange)="pageList = $event"></pagination-controls>
</div>
You can customize the pagination-template and try adding these buttons
<pagination-template #p="paginationApi" [id]="config.id
(pageChange)="config.currentPage = $event">
<div class="custom-pagination">
<div class="pagination-first-page">
<span (click)="p.setCurrent(1)">
First Page
</span>
</div>
<div class="pagination-previous" [class.disabled]="p.isFirstPage()">
<span *ngIf="!p.isFirstPage()" (click)="p.previous()">
<
</span>
</div>
<div class="page-number" *ngFor="let page of p.pages" [class.current]="p.getCurrent() === page.value">
<span (click)="p.setCurrent(page.value)" *ngIf="p.getCurrent() !== page.value">{{ page.label }}</span>
<div *ngIf="p.getCurrent() === page.value">
<span>{{ page.label }}</span>
</div>
</div>
<div class="pagination-next" [class.disabled]="p.isLastPage()">
<span *ngIf="!p.isLastPage()" (click)="p.next()"> > </span>
</div>
<div class="pagination-last-page">
<span (click)="p.setCurrent(p.getLastPage())">
Last Page
</span>
</div>
</div>
</pagination-template>
I am consuming an API and I want to know how you can change the state of a button that is inside * NgFor, the problem is that when I click to change the state from favorite to non-favorite, it changes them all as only the state can change one's? and if possible maintain the state of let's say favorite
When the user clicked it, I have tried it in several ways but I could not
Service
import { HttpClient } from "#angular/common/http";
#Injectable({
providedIn: 'root'
})
export class ServiceService {
constructor(private http: HttpClient) { }
private url = 'https://rickandmortyapi.com/api/';
getAllApi(){
return this.http.get(`${this.url}/character`)
}
paginacion(paginacion:number){
return this.http.get(`${this.url}/character/?page=${paginacion}`)
}
}
home.component.ts
import { Component, OnInit } from '#angular/core';
import { ServiceService } from 'src/app/services/service.service';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
Personajes: any[] = []
NuevosPersonajes: any[] = []
public suma = 1;
public status = false;
constructor(private apiService: ServiceService) {
this.allApi()
}
ngOnInit(): void {
}
allApi() {
this.apiService.getAllApi()
.subscribe((data: any) => {
this.Personajes = data.results;
console.log(data)
})
}
nextApi(paginacion: number) {
this.suma = this.suma + 1;
console.log(this.suma)
this.apiService.paginacion(this.suma)
.subscribe((data: any) => {
this.NuevosPersonajes = data.results
console.log(data)
})
}
statusFav(status:boolean){
this.status = status
}
}
html
<div class="container mt-5">
<button (click)="nextApi(1)" class="btn btn-outline-dark m-2">Next</button>
<div class="card-columns" *ngIf="suma < 2; else elseBlock">
<div class="card text-center" *ngFor="let personaje of Personajes">
<img class="card-img-top" [src]="personaje.image" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{personaje.name}}</h5>
<p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional
content. This content is a little bit longer.</p>
</div>
<button (click)="statusFav(false)" *ngIf="status; else elseFav" class="btn btn-success btn-block"><i class="far fa-star"></i> Favorite</button>
<ng-template #elseFav>
<button (click)="statusFav(true)" class="btn btn-outline-success btn-block"><i class="fas fa-star"></i> Favorite</button>
</ng-template>
</div>
</div>
<ng-template #elseBlock>
<div class="card-columns">
<div class="card text-center" *ngFor="let nuevoPersonaje of NuevosPersonajes">
<img class="card-img-top" [src]="nuevoPersonaje.image" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{nuevoPersonaje.name}}</h5>
<p class="card-text">This is a longer card with supporting text below as a natural lead-in to
additional
content. This content is a little bit longer.</p>
</div>
</div>
</div>
</ng-template>
</div>
thanks to the one who can help me.
The problem is this.status is not tied to any particular item, that's a component wide state. You need to have a status property that changes when you click favourite button.
Here stackblitz example
Instead of using a class level status variable to save the favourite status for a user, add a status key on the each user object in the Personajes array.
allApi function below elaborates how to add a status property on each user object.
private allApi() {
this.apiService.getAllApi()
.subscribe((data: any) => {
this.Personajes = data.results.map ( user => {
if ( user && typeof user === 'object') {
user['status'] = true;
}
return user;
});
console.log(data)
})
}
statusFav function toggles between the user status i.e. set it true if it was false initially and vice versa.
public statusFav (user:any) {
user.status = !user.status
}
You can also use the value of user.status in an ngClass directive to toggle between 'far' and 'fas' classes instead of repeating the button code with an ngIf and ngElse condition
<div class="card-columns" *ngIf="suma < 2; else elseBlock">
<div class="card text-center" *ngFor="let personaje of Personajes">
<img class="card-img-top" [src]="personaje.image" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{personaje.name}}</h5>
<p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional
content. This content is a little bit longer.</p>
</div>
<button (click)="statusFav(user.status)"
class="btn btn-success btn-block">
<i *ngIf="user.status" [ngClass]="{'fas' :user.status, 'far': !user.status}" class="fa-star"></i>
</div>
</div>
</div>
I'm working with Reactive Forms and I'm trying to pass my form down to child components, but I'm running into the error above. Initially at the top level of the form I was using a FormArray to hold my form and that was working fine before I tried passing it down to the child components. Thanks to this post I now know that the top level of a form should be a FormGroup and the FormArray should be a child of the FormGroup.
So now I am nesting my FormArray inside of a FormGroup and I'm getting the error above. I'm not sure what I'm doing wrong? Below in the relevant code.
// Parent component.ts
ngOnInit() {
if (!!this.rows) {
this.tableForm = new FormArray([]);
this.rows.forEach((row) => {
this.rowGroup = new FormGroup({})
this.columns.forEach(column => {
this.rowGroup.addControl(column.key, new FormControl(row[column.key]));
});
this.tableForm.push(this.rowGroup);
})
this.tableGroup = new FormGroup({
rows: new FormControl(this.tableForm)
})
}
}
// Parent HTML
<section
*ngIf="!!modal"
class="modal__mask">
<section
class="modal__container"
#carousel
[ngStyle]="{'left': start + 'px'}"
(window:resize)="onResize($event)"
[formGroup]="tableGroup">
<div
*ngFor='let row of selectedRows; let i = index'
class="modal modal__large"
[formArrayName]="rows">
<div
[formGroupName]="i"
[ngClass]="{'opacity': modalPage !== i}">
<div class="modal__header modal__header--large">
<h6>Edit Employee Details</h6>
</div>
<div class="u-flex u-wrap">
<div
class="u-flex modal__body"
style="width: 50%"
*ngFor="let column of columns">
<div
*ngIf="column.label"
class="input__wrapper"
[ngClass]="{'input__wrapper--inline': layout === 'horizontal'}">
<z-input
*ngIf="column.label"
class="u-maxX"
[group]="tableGroup"
[config]="column">
</z-input>
<!-- <div>
<label
class="input__label">
<p class="t-bold t-data">{{column.label}}</p>
</label>
<div class="z-input__default">
<input
class="input u-maxX"
[formControlName]="column.key"
[value]="row[column.key]">
</div>
</div> -->
</div>
</div>
<section class="modal__footer u-fillRemaining">
<div class="u-flex">
<button
class="button button--medium"
(click)="nextSelectedRow()">
<div class="button__content">
<i
class="icon icon--medium"
*ngIf="!!icon">
{{icon}}
</i>
<span>Skip</span>
</div>
</button>
</div>
<div class="u-flex">
<button
class="button button--low"
(click)="reset(row, i)">
<div class="button__content">
<i
class="icon icon--medium"
*ngIf="!!icon">
{{icon}}
</i>
<span>Reset</span>
</div>
</button>
<button
class="button button--low"
(click)="saveChanges(row, i)">
<div class="button__content">
<i
class="icon icon--medium"
*ngIf="!!icon">
{{icon}}
</i>
<span>Save Changes</span>
</div>
</button>
</div>
</section>
</div>
</div>
</div>
// Child component.ts
#Input() config;
#Input() group: FormGroup;
#Input() view: string;
#Input() layout: string;
// Child HTML
<div
class="input__wrapper"
[ngClass]="{'input__wrapper--inline': layout === 'horizontal'}"
[formGroup]="group"
[ngSwitch]="config.type">
<label
class="input__label"
*ngIf="!!config.label">
<p class="t-bold t-data">{{config.label}}</p>
</label>
<z-select
*ngSwitchCase="'select'"
[config]="config"
[group]="group"
[view]="view"
gridColumn="1 / 5">
</z-select>
<div class="z-input__default">
<input
*ngSwitchDefault
class="input u-maxX"
[formControlName]="config.key"
[attr.type]="config.type"
[attr.placeholder]="config.placeholder">
</div>
Need some expert help to show api-answer data in a bootstrap modal.(the other thread about this in SO did not answer this question)
I have a .ts file that looks like below.
NgbdModal1Content and NgbdModalStacked are the ones I'm having trouble with. Ignore NgbdModal2Content & NgbdModal3Content and their components.
Also, I added a sleep part to make sure the api answer had come back and populated
getResultatFromApi3: string [] = [];
getResultatFromApi4: Observable<Station> [];
Before the modal is rendered. The getResultatFromApiX are console logged before modal is rendered.
import { Component, Injectable } from '#angular/core';
import { NgbActiveModal, NgbModal } from '#ng-bootstrap/ng-bootstrap';
import { GetApiService } from './get-api.service';
import { Observable } from 'rxjs/Observable';
import { Station } from './station';
import { Station2 } from './station2';
#Component({
selector: 'app-modal-stacked',
templateUrl: './modal-stacked2.html',
})
// tslint:disable-next-line:component-class-suffix
export class NgbdModal1Content {
constructor(private modalService: NgbModal, public activeModal: NgbActiveModal) {}
open() {
this.modalService.open(NgbdModal2Content, {
size: 'lg'
});
}
open2() {
this.modalService.open(NgbdModal3Content, {
size: 'lg'
});
}
}
#Component({
template: `
<div class="modal-header">
<h4 class="modal-title">Teststation 1</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Kör test här!</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>
`
})
// tslint:disable-next-line:component-class-suffix
export class NgbdModal2Content {
constructor(public activeModal: NgbActiveModal) {}
}
#Component({
template: `
<div class="modal-header">
<h4 class="modal-title">Teststation 2</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Kör test här!</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>
`
})
// tslint:disable-next-line:component-class-suffix
export class NgbdModal3Content {
constructor(public activeModal: NgbActiveModal) {}
}
#Component({
// tslint:disable-next-line:component-selector
selector: 'ngbd-modal-stacked',
templateUrl: './modal-stacked.html'
})
// tslint:disable-next-line:component-class-suffix
export class NgbdModalStacked {
constructor(private modalService: NgbModal, private _getApiService: GetApiService) {}
getResultatFromApi3: string [] = [];
getResultatFromApi4: Observable<Station> [];
getApiData: string [];
// Triggered when opening Modal (that contains two buttons for two other modals
open() {
this._getApiService.method3Call().subscribe(function(data) {
console.log('Test från Y-Tube-videon', data);
this.getResultatFromApi4 = data;
this.getResultatFromApi3 = data;
console.log(this.getResultatFromApi4);
console.log(this.getResultatFromApi3);
});
this.delay(5000).then(any => {
this.modalService.open(NgbdModal1Content);
console.log('du klickade på Teststationer');
});
}
async delay(ms: number) {
await new Promise(resolve => setTimeout(() => resolve(), ms)).then(() => console.log('fired'));
}
}
My api call comes back with information when I trigger Open() in NgbdModalStacked part and answer looks like this, from console log:
I moved the NgbdModal1Content hmtl part to a separate html file to make it easier. That html file looks like this:
<div class="modal-header">
<h4 class="modal-title">Teststationer</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p><button class="btn btn-lg btn-outline-primary" (click)="open()">Teststation 1 {{getResultatFromApi4}}</button></p>
<p><button class="btn btn-lg btn-outline-primary" (click)="open2()">Teststation 2</button></p>
<p>hej2<p>
<ul *ngFor="let data of getResultatFromApi3">
<li>Reported: {{data.Name}} <span>Mer info</span></li>
</ul>
<table>
<tr *ngFor="let data of getResultatFromApi3">
<td>{{data.Name}}</td>
</tr>
</table>
<ul>
<li *ngFor="let data of getResultatFromApi4">
{{data.Name}}
</li>
</ul>
<ul>
<li *ngFor="let data of getResultatFromApi4">
{{data.Name}}
</li>
</ul>
<p>hejigen2<p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>
But it doesn't output the data (see pic below) and I can't understand what I'm doing wrong? Tried data.Name and data.name, have both string and object array but api answer is not displayed but the other things in p are displayed.
HOW DO I MAKE THE DATA.NAME SHOW?
Thank you
public getResultatFromApi10 = [];
this._getApiService.method3Call().subscribe(
data => data.forEach(item => {this.getResultatFromApi10.push(item); })
);
This code made it work for me. The other subscribe would output info in the console.log but not carry any data from .ts to the html-part wheras the push(item) seem to have done the trick.
Hope this can help somebody else who might run into the same problem.
I have crud app , which user can add comments , I want comments to be displayed under each section commented, now all added comments displays below all section.
here is components ts
import { Component, OnInit } from '#angular/core';
import { Task } from '../model/task.model';
import { Comment } from '../model/comment.model';
import { Router } from '#angular/router';
import { UserService } from '../service/user.service';
import {first} from 'rxjs/operators';
import {FormBuilder, FormGroup, Validators} from '#angular/forms';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-task-list',
templateUrl: './task-list.component.html',
styleUrls: ['./task-list.component.scss']
})
export class TaskListComponent implements OnInit {
tasks: Task[];
comments: Comment[];
// tslint:disable-next-line:max-line-length
constructor(private formBuilder: FormBuilder, private router: Router, private activeRouter: ActivatedRoute, private userService: UserService) { }
addForm: FormGroup;
ngOnInit() {
this.userService.getTask()
.subscribe( data => {
this.tasks = data;
});
this.activeRouter.params.subscribe((params) => {
// tslint:disable-next-line:prefer-const
let id = params['id'];
this.userService.getComments(id)
.subscribe(data => {
this.comments = data;
});
});
this.addForm = this.formBuilder.group({
id: [],
author: ['', Validators.required],
description: ['', Validators.required],
});
}
addComments(task_id) {
const formData = this.addForm.value;
formData.task_id = task_id;
this.userService.addComments(formData)
.subscribe(data => {
this.comments.push(this.addForm.value);
});
this.router.navigate(['task-list']);
}
}
Here is task list html i have
<div class="container task-list">
<div class="row">
<div class="col-sm-8">
<div class="panel panel-white post panel-shadow" *ngFor="let task of tasks">
<div class="post-heading">
<div class="pull-left meta">
<div class="title h4">
<b>{{task.title}}</b>
</div>
<h6 class="text-muted time">1 minute ago</h6>
</div>
</div>
<div class="post-description">
<p>{{task.description}}</p>
<div class="stats">
<a href="#" class="btn btn-default stat-item">
<i class="fa fa-thumbs-up icon"></i>2
</a>
<a href="#" class="btn btn-default stat-item">
<i class="fa fa-thumbs-down icon"></i>12
</a>
</div>
</div>
<form class="post-form" [formGroup]="addForm" (ngSubmit)="addComments(task.id)">
<div class="form-group task-group">
<div class="form-group">
<label class="">Author</label>
<input type="text" class="form-control" formControlName="author" id="author" />
</div>
<div class="form-group">
<label class="">Comments</label>
<textarea class="form-control task-textarea" rows="1" formControlName="description" id="description" ></textarea>
</div>
</div>
<button class="btn btn-default btn-submit">Submit</button>
</form>
</div>
</div>
<div class="col-sm-8">
<div class="panel panel-white post panel-shadow" *ngFor="let comment of comments">
<div class="post-heading">
<div class="pull-left image">
<img src="http://bootdey.com/img/Content/user_1.jpg" class="img-circle avatar" alt="user profile image">
</div>
<div class="pull-left meta">
<div class="title h5">
<b>{{comment.author}}</b>
made a post.
</div>
<h6 class="text-muted time">1 minute ago</h6>
</div>
</div>
<div class="post-description">
<p>{{comment.description}}</p>
<div class="stats">
<a href="#" class="btn btn-default stat-item">
<i class="fa fa-thumbs-up icon"></i>2
</a>
<a href="#" class="btn btn-default stat-item">
<i class="fa fa-thumbs-down icon"></i>12
</a>
</div>
</div>
</div>
</div>
</div>
</div>
Here is services for getting task and comments
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { User } from '../model/user.model';
import { Task } from '../model/task.model';
import { Comment } from '../model/comment.model';
#Injectable({
providedIn: 'root'
})
export class UserService {
constructor(private http: HttpClient) { }
baseUrl = 'http://localhost:3000/users';
taskUrl = 'http://localhost:3000/task';
commentsUrl = 'http://localhost:3000/comment';
getUsers() {
return this.http.get<User[]>(this.baseUrl);
}
getUserById(id: number) {
return this.http.get<User>(this.baseUrl + '/' + id);
}
createUser(user: User) {
return this.http.post(this.baseUrl, user);
}
updateUser(user: User) {
return this.http.put(this.baseUrl + '/' + user.id, user);
}
deleteUser(id: number) {
return this.http.delete(this.baseUrl + '/' + id);
}
createTask(task: Task) {
return this.http.post(this.taskUrl, task);
}
getTask() {
return this.http.get<Task[]>(this.taskUrl);
}
addComments(comment: Comment) {
return this.http.post(this.commentsUrl, comment);
}
getComments(id: number) {
return this.http.get<Comment[]>(this.commentsUrl);
}
/*
getComments(id: number) {
return this.http.get<Comment[]>(this.commentsUrl + id);
}
*/
}
Problem: when I add comments in a certain task , displays beloww all task I have ,
Here is image how it look after adding comment
Here is what I want
What do I need to change in my code to get what I want? thanks