Angular2 - pass dynamically loaded parameters to function while doing dropdown value selection - javascript

Please check that, I am passing the parameters of li tag click function of updateId method in the correct format or not ? The errors in the console shows that line only....
My app.component.html code is
<div class='form-group' style="width: 100%;">
<div class="btn-group" style="width: 100%;">
<button type="button" class="btn btn-default" style="width : 75%;text-align: left;">{{name}}</button>
<button type="button" data-toggle="dropdown" class="btn btn-default dropdown-toggle"><span class="caret"></span></button>
<ul class="dropdown-menu" style="width: 75%;">
<li *ngFor="let result of jsonList" ><a class="dropdown-item" (click)="updateId('{{result.id}}', '{{result.name}}')" >{{result.name}}</a>
</li>
</ul>
</div>
</div>
My app.component.ts is ,
import { HomeService } from '../../services/home.service';
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-home-component',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
id: string;
name : string;
jsonList : any;
constructor(private homeservice: HomeService) { }
ngOnInit() {
this.id = null;
this.name = "SELECT";
this.jsonList= [{"Id" : "F1", "name" : "FONE"}, {"id" : "F2", "name" : "FTWO"}]
}
updateId(id : string, name : string) : void {
this.id = id;
this.name = name;
}
}
It is not working. The error is on the li tag click function method passing the dynamic parameters from the jsonList. So pls help me to get resolve.

Don't use the handlebars {{ }} in event bindings such as the (click) attribute - they will be evaluated against the Component instance automatically. and the single quotes are not needed either. Use it like so:
<li *ngFor="let result of jsonList">
<a (click)="updateId(result.id, result.name)">{{result.name}}</a>
</li>

You don't need {{ }} while specifying arguments to an event handlers (ng-click). The correct syntax would be
<li *ngFor="let result of jsonList">
<a (click)="updateId(result.id, result.name)">{{result.name}}</a>
</li>

Related

Change login button to logout in angular 13

I have a simple list with two buttons. I want to be able to show one or the other depending on whether I'm logged in.
<div>
<li class="nav-item">
<button *ngIf="token === ''" type="button" class="btn btn-dark btn-lg fs-4" (click)="login()">Inicia sesión</button>
<button *ngIf="token != ''" type="button" class="btn btn-dark btn-lg fs-4" (click)="logout()">Cerrar sesión</button>
</li>
</div>
I tried simply putting the ngIf but it doesn't make it instant, besides that since the log in is in another component I don't really know how to change that from there.
this is my component:
import { Component, ElementRef, ViewChild} from '#angular/core';
import { Router } from '#angular/router';
import { faHamburger } from '#fortawesome/free-solid-svg-icons';
import { UsersService } from './services/user.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'my-app';
token = this.userService.getToken();
#ViewChild('clickLogout')clickLogout:ElementRef;
faHamburger = faHamburger;
constructor(public userService: UsersService, public router: Router) { }
logout(){
this.userService.logout();
this.router.navigateByUrl('/login');
}
login(){
this.router.navigateByUrl('/login');
}
}
So as it is, I would need to reload the page every time I need one button or another and I need it to do it instantly when I log in or log out.
try to use that in html,
<div *ngIf="token === ''; else empty">
<button type="button" class="btn btn-dark btn-lg fs-4"
(click)="login()">Inicia
sesión</button>
</div>
<ng-template #empty>
<button type="button" class="btn btn-dark btn-lg fs-4"
(click)="logout()">Cerrar sesión</button>
</ng-template>
in ts call the token in the ngOnInit method and change the route (/login to /logout when you navigate) :
export class AppComponent implements OnInit {
//code...
token=''
ngOnInit(): void {
this.token = this.userService.getToken();}
You should use BehaviorSubject to store the token in the service, add:
public token$ = new BehaviorSubject<string>(null);
then use this.token$.next(valueFromRequest); when you will receive token value and
this.token$.next(null); to reset it.
In html code use ngIf in that way:
<button *ngIf="(userService.token$ | async)" type="button" [...]>Logout</button>
<button *ngIf="!(userService.token$ | async)" type="button"[...]>Login</button>

How to work with variables from a loop in HTML and with a component property?

The data I work with (bosses[]) has a boss object with contains the key-value email which is an string. I want to create the anchor with that string in the HTML. Also note that there's a loop in HTML that allows to access to each boss in bosses[].
So how can I access to create an anchor with boss.email which it only exists in the HTML loop?
I've tried <a [href]=`"mailto: + boss.email"></a> but doesn't work.
the html:
<div class="boss" *ngFor="let boss of bosses" >
<div class="boss-text">
<div class="boss-text-name">{{boss.name}} </div>
<div>{{boss.email}}</div>
<a [href]="mailto: + boss.email"></a>
</div>
</div>
The component:
import { Component, Input, OnInit } from '#angular/core';
import { boss} from 'interfaces'
#Component({
templateUrl: 'boss-cell.component.html',
selector: 'boss-cell',
})
export class BossCellComponent implements OnInit {
constructor() {}
bosses: any[] = [{
email: 'kennedy#gmail.com',
name: 'kennedy',
}]
}
You're close! I think this is what you're looking for:
<div class="boss" *ngFor="let boss of bosses" >
<div class="boss-text">
<div class="boss-text-name">{{boss.name}} </div>
<a [href]="'mailto:' + boss.email">{{ boss.email }}</a>
</div>
</div>
You can use interpolation as Suraj already mentionned in the comments, or bind to a function creating the string. Depending on weather you are going to link other elements to the mail, you should pick the cleanest option for you.
Template
<div class="boss" *ngFor="let boss of bosses; let i = index">
<div class="boss-text">
<div class="boss-text-name">{{ boss.name }}</div>
<a [href]="getMail(i)">{{ boss.email }}</a>
</div>
</div>
Script
bosses: any[] = [{
email: 'kennedy#gmail.com',
name: 'kennedy',
}]
getMail(index: number) {
return 'mailto:' + this.bosses[index].email
}
You need to update this line
<a [href]="'mailto:' + boss.email">{{ boss.email }}</a>

Need dynamically created buttons to work independently in Angular

In Angular i have dynamically created a group of buttons that all have the same action (to show text when clicked) everything works fine yet when I click one button they all perform the action. I need them to work independently of each other. I have dynamically made a different id for each button and was wondering if there was a way to us the id to have them work independently.
Button HTML and TS files:
<button id="{{index}}" class="btn btn-secondary" style="float: right;" (click)="onClick()">Discription</button>
import { Component, EventEmitter, OnInit, Output, Input } from '#angular/core';
#Component({
selector: 'app-discription-btn',
templateUrl: './discription-btn.component.html',
styleUrls: ['./discription-btn.component.css']
})
export class DiscriptionBtnComponent implements OnInit {
#Output() btnClick = new EventEmitter();
#Input() index!: number
constructor() { }
ngOnInit(): void { }
onClick() {
this.btnClick.emit();
}
}
Button Parent HTML and TS files:
<div class="card mb-4 h-100">
<img class="card-img-top-other" src= "{{ post.link }}" />
<div class="card-body">
<div class="small text-muted"> {{ post.created }} <app-discription-btn (btnClick) = "toggleDiscription()" [index] = index></app-discription-btn> </div>
<h2 class="card-title h4"> {{ post.title }} </h2>
<div *ngIf="showDiscription">
<p class="card-text"> {{ post.summary }} </p>
<a class="btn btn-primary" href="#!">Read More -></a>
</div>
</div>
</div>
import { Component, OnInit, Input } from '#angular/core';
import { Subscription } from 'rxjs';
import { BlogPost } from 'src/app/Post';
import { DiscriptionUiService } from 'src/app/services/discription-ui.service';
#Component({
selector: 'app-other-posts',
templateUrl: './other-posts.component.html',
styleUrls: ['./other-posts.component.css']
})
export class OtherPostsComponent implements OnInit {
#Input() post! : BlogPost
#Input() index! : number;
showDiscription : boolean = false;
subscription : Subscription;
constructor(private discritpionService: DiscriptionUiService) {
this.subscription = this.discritpionService.onToggle().subscribe((value) => (this.showDiscription = value));
}
ngOnInit(): void {
}
toggleDiscription(){
this.discritpionService.toggleDiscription();
}
}
Main HTML and TS files:
<div class="container">
<div class="row">
<div class="col-lg-8"><app-featured-post *ngFor="let post of posts; let i = index;" [post] = "post" [index] = "i"></app-featured-post></div>
<div class="col-lg-4"><app-side-widgets></app-side-widgets></div>
<app-other-posts *ngFor="let post of posts | myFilterPipe:filterargs; let i = index;" [post] = "post" [index] = "i" class="col-lg-4" style="padding-top: 10px;" ></app-other-posts>
<nav aria-label="Pagination">
<hr class="my-0" />
<ul class="pagination justify-content-center my-4">
<li class="page-item disabled"><a class="page-link" href="#" tabindex="-1" aria-disabled="true">Newer</a></li>
<li class="page-item active" aria-current="page"><a class="page-link" href="#!">1</a></li>
<li class="page-item"><a class="page-link" href="#!">Older</a></li>
</ul>
</nav>
</div>
</div>
import { Component, OnInit } from '#angular/core';
import { BlogPostService } from 'src/app/services/blog-post.service';
import { BlogPost } from '../../Post';
#Component({
selector: 'app-posts',
templateUrl: './posts.component.html',
styleUrls: ['./posts.component.css']
})
export class PostsComponent implements OnInit {
filterargs = {title: 'The Beginning'}
posts: BlogPost[] = [];
constructor(private postService: BlogPostService ) { }
ngOnInit(): void {
this.postService.getPosts().subscribe((posts) => (this.posts = posts));
}
}
Any ideas would be a great help. Thank you ahead of time!

Angular 6 convert string to an Html using pipe

My input string is
html:string="<a role="button" class=" fas fa-trash-alt fa-1x" title="Remove Link" href="#"></a>"
I want this to be converted into an raw html
Pipe:
import { Pipe, PipeTransform } from '#angular/core';
import { DomSanitizer } from '#angular/platform-browser'
#Pipe({
name: 'htmldecoder'
})
export class HtmldecoderPipe implements PipeTransform {
constructor(private sanitized: DomSanitizer) { }
transform(value) {
return this.sanitized.bypassSecurityTrustHtml(value);
}
}
Html Code :
<div>
<div [innerHtml]="html | htmldecoder">
</div>
</div>
The output getting in UI is
<a role="button" class="fas fa-trash-alt fa-1x" title="Remove Link" href="#"></a>
Expected Output Should be the Button
Make this following changes in your code and it will work, the code quite simple for self-explanation
app.component.ts
html = `html:string="<a role="button" class=" fas fa-trash-alt fa-1x" title="Remove Link" href="#">aditya</a>"`;
pipe
transform(value) {
value = value.substring(13, value.length-1);
var doc = new DOMParser().parseFromString(value, "text/html");
const value123 = doc.documentElement.textContent;
return this.sanitized.bypassSecurityTrustHtml(value123);
}
app.component.html
<div [innerHTML]="html | htmldecoder">

Angular: passing attributes to Dynamic component template

I have a component created, and I want to pass an attribute though the component to the template.
This is the component:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-card-generator',
templateUrl: './card-generator.component.html',
styleUrls: ['./card-generator.component.css'],
inputs: ['id', 'collapseid', 'headingid','collapsehashid']
})
export class CardGeneratorComponent implements OnInit {
bindings: {
headingid:'#?',
collapseid:'#?',
collapsehashid
}
constructor() { }
ngOnInit() {}
and this is the template:
<button class="btn btn-link collapsed" style="text-decoration:none;" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
{{id}}
</button>
</h5>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample">
<div class="card-body"></div>
</div>
created components are placed in home.component this way:
<div id="cardDivContainer" >
<app-card-generator id="Chart 1" collapsehashid="data-target='#collapseOne'" collapseid="aria-controls='collapseOne'" headingid="aria-labelledby='headingOne'"></app-card-generator>
<app-card-generator id="Chart 2" collapsehashid="data-target='#collapseTwo'" collapseid="aria-controls='collapseTwo'" headingid="aria-labelledby='headingTwo'"></app-card-generator>
</div>
I just need to set the "data-target", "aria-labelledby", and the "aria-controls" attributes for each component (depending on the component ID).
I am new to Angular, I hope the above make sense.
You can use #Input to reference the elements within the component. The elements can be passed as parameter outside. Something like:
import {
Component,
OnInit,
Input,
Output,
EventEmitter
} from '#angular/core';
#Component({
selector: 'app-card-generator',
styleUrls: ['./card-generator.component.css'],
templateUrl: './card-generator.component.html'
})
export class CardGeneratorComponent implements OnInit {
#Input() id: string;
#Input() collapseid: string;
#Input() headingid: string;
#Input() collapsehashid: string;
constructor() {
}
ngOnInit() {}
}
If the attributes do not exist in the element you are referencing, you can use attr.attribute and use the {{}} notation
<button class="btn btn-link collapsed" style="text-decoration:none;" type="button" data-toggle="collapse" attr.data-target="{{'#' + collapseid}}" aria-expanded="false" attr.aria-controls="collapseid">
</button>
<div id="{{collapseid}}" class="collapse" attr.aria-labelledby="{{headingid}}" data-parent="#accordionExample">
<div class="card-body"></div>
</div>
And finally you can access the attributes created in your component in the call from the outside
<div id="cardDivContainer" >
<app-card-generator id="Chart 1" collapsehashid="collapseOne" headingid="headingOne"></app-card-generator>
<app-card-generator id="Chart 2" collapsehashid="collapseTwo" headingid="headingTwo"></app-card-generator>
</div>
More #Input and #Output details in this link:
https://stackblitz.com/edit/card-generator-sample?file=src%2Fapp%2Fapp.component.html

Categories

Resources