I need to capture data about the ngFor loop instance that is being rendered in the view, to then output it to a different view that renders extra information about the first information captured in the ngFor loop.
Example:
.ts file
user = [
{name: "Lucho", lastname: "Pai"},
{name: "Debora", lastname: "Melo"},
{name: "Elba", lastname: "Lazo"}
]
.html file
<ul *ngFor="let user of users">
<li>
Name: {{ user.name }}
Lastname: {{user.lastname }}
</li>
</ul>
That will render 3 , one for each user. I want to click in any of them and go to another view that shows me detail information about the lastname family. I.e., if I click in the "Elba" , I want to navigate to a full description of the "Lazo" family. So I need to capture that user information to navigate and to then make a request to my database to get the "Lazo" family information.
I've been thinking about this some days, but I cant grasp the concept that I need to understand to do it. It's to abstract for me. Between input(), output(), viewchild(), etc, I'm just tangling myself.
I really hope I explained myself,
Regards.
you can pass the value of selected family to the child component using #Input like this
component.ts
selectedFamily:any;
html
<ul *ngFor="let user of users">
<li (click)="selectedFamily=user;">
Name: {{ user.name }}
Lastname: {{user.lastname }}
</li>
</ul>
<detail-component *ngIf="selectedFamily" [value]="selectedFamily"></detail-component>
detail.component.ts
#Input() value:any;
UPDATE :- If the you want to navigate to another route to display the detail of the family you can use parameter to pass the unique id of the familiy
e.g
<ul *ngFor="let user of users">
<li (click)="onFamilySelect(user)">
Name: {{ user.name }}
Lastname: {{user.lastname }}
</li>
</ul>
component.ts
detailUrl:string="details/"// example route
onFamilySelect(user:any){
this.router.navigate(this.detailUrl+user.UserId)//assuming UserId is unique Id
}
}
on the new component
ngOnInit(){
let userId = this.route.snapshot.param['id'];
//and get the detail from db by userid
}
on route.module.ts
export const routes: Routes = [
{ path: 'details/:id', component: NewComponent }
];
dear Kaiser I think you can use the local storage as in this example
first.ts
//first component
//Inject Router in your constructor from
import { Router } from '#angular/router';
constructor(private router:Router) { }
navigateToOtherComponent(user){
localStorage.setItem("user",user);
this.router.navigate(['/second.ts']);
}
.html
//first component
// Add Event (Click) on the <li> tag or add a button aside with your content
<li (Click)="navigateToOtherComponent(user)">
Name: {{ user.name }}
Lastname: {{user.lastname }}
</li>
second.ts
//second component
constructor() {
const user = localStorage.getItem("user");
}
Assuming your detail component has a route configured and is called details. Hence use this answer only if you are routing to the details component. If you are displaying the details on the parent component itself, use the answer given by someone else below.
In your list.component.html
<ul *ngFor="let user of users">
<li>
Name: {{ user.name }}
Lastname: {{user.lastname }}
<button (click)="showDetails(user.name)">Details</button>
</li>
</ul>
In your list.component.ts
constructor(private router: Router){}
user = [
{name: "Lucho", lastname: "Pai"},
{name: "Debora", lastname: "Melo"},
{name: "Elba", lastname: "Lazo"}
]
showDetails(user){
this.router.navigate(['/details', { user: user}]);
}
In your details component this is how you receive the data:
ngOnInit() {
this.user$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) => {
this.user = params.get('user');
})
);
//Do something with this.user
}
Hope this helps.
You can pass the user object in a function and run the navigation logic based on that specific user. For example in the html file you can bind and event to the ul:
<ul *ngFor="let user of users">
<li (click)="navigateBasedOnUser(user)">
Name: {{ user.name }}
Lastname: {{user.lastname }}
</li>
</ul>
And then in the component, you can define navigateBasedOnUser function to navigate. For example:
user = [
{name: "Lucho", lastname: "Pai"},
{name: "Debora", lastname: "Melo"},
{name: "Elba", lastname: "Lazo"}
]
navigateBasedOnUser(user){
// the user parametere here will have the user object of the `li` the user clicked on. you can access all the values of the user i.e. name, last name e.t.c.
this.router.navigate(["detailsComponent",user.name])
}
Related
I want to remove the matChip on click of cancel icon
here is my code
<mat-chip-list>
<mat-chip
*ngFor="let user of data.users"
[removable]="true"
[selectable]="true"
(removed)="remove(user.id)">
{{user.name}}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
</mat-chip-list>
Even though [removable]="true" is set it is not removing the clicked chip
I have been following this docs example
Working example. Please, find the update files from your above link (which is available in your question) as below, while other files remains as same. If you want to check the working code, then try to replace the whole code in respective files of your link with below code to same files.
NOTE: for better readability, I have removed input element with add functionality.
chips-input-example.html
<mat-form-field class="example-chip-list">
<mat-chip-list #chipList aria-label="User selection">
<mat-chip *ngFor="let user of data.users" [selectable]="selectable" [removable]="removable"
(removed)="remove(user.id)">
{{user.name}}
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
</mat-chip-list>
</mat-form-field>
chips-input-example.ts
import {Component} from '#angular/core';
interface User {
name: string;
id: number;
}
interface Data {
users: User[];
}
#Component({
selector: 'chips-input-example',
templateUrl: 'chips-input-example.html',
styleUrls: ['chips-input-example.css'],
})
export class ChipsInputExample {
selectable = true;
removable = true;
data: Data = {
users: [
{name: 'User1', id: 0},
{name: 'User2', id: 1},
{name: 'User3', id: 2},
]};
remove(getId: number): void {
this.data.users = [...this.data.users.filter(({id}) => getId !== id)];
}
}
chips-input-example.css
.example-chip-list {
width: 100%;
}
How do I create Mock data to plug in and test displays? Everytime, we want to view an HTML rendering, have to literally copy and paste data into Typescript file. Is there any toolset to conduct this?
Currently testing #Inputs, which are being displayed in HTML
In researching following options,
It is not an API, so cannot use InMemoryDbService from “angular-in-memory-web-api” https://www.techiediaries.com/angular-inmemory-web-api/
Also not database, so cannot apply json-server https://medium.com/letsboot/the-perfect-mock-backend-to-start-with-an-angular-application-3d751d16614f
What options exist to quickly swap Inputs? or do people have to copy and paste into each file, is this customary in Angular?
Typescript
export class CustomerView implements OnInit {
#Input() customer: Customer;
this.customer.name = "Joe";
this.customer.address = "123 Maple STreet";
this.customer.city = "Atlanta";
this.customer.state = "GA";
this.customer.zip= "30314";
this.customer.phone = "555-444-77777";
HTML
<div class = "row">
<div> {{customer.name}} </div>
<div> {{customer.address}} </div>
<div> {{customer.city}} </div>
<div> {{customer.state}} </div>
<div> {{customer.zip}} </div>
<div> {{customer.phone}} </div>
</div>
Display example plcture
You can create a json file or Object with the required fields.
customerDummy = {
name: "Joe",
address: "123 Maple STreet",
city: "Atlanta",
state: "GA",
zip: "30314",
phone: "555-444-77777",
}
Whenever you are you create a variable just assign the value. For eg
#Input() customer: Customer = customerDummy;
I have an array that gives teachers information. And I have a list component that lists these teachers. I want to a combobox and filter for this array.
this is my array
private _infoList: Array<AcademicPersonnelInfoModel> = [
{
id: '1',
title: 'Prof. Dr.',
firstName: 'Atakan',
lastName: 'bir'
},
{
id: '2',
title: 'Prof. Dr.',
firstName: 'Atakan',
lastName: 'iki'
},
{
id: '3',
title: 'Prof. Dr.',
firstName: 'Atakan',
lastName: 'uc'
},
];
this is my .html
<div class="col top-bar">
<div class="container">
<div class="tab-content">
<div class="tab-pane active">
<input type="text" ng-model=search.accountName>
<select ng-model="search.id" id="">
<option value=''>All</option>
<option value=1>1</option>
<option value=2>2</option>
</select>
<table ng-table="tableParams" class="table">
<tr ng-repeat="account in $data | filter:search.lastName | filter:search.id">
<td data-title="'id'">
{{account.account.accountId.id}}
</td>
<td data-title="'lastName'">
{{account.account.accountName}}
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
What should i do in typescript to be able to filter this list?
this is my ts file
export class AcademicPersonnelListComponent implements OnInit {
/** */
/** */
private _academicPersonelList: Array<AcademicPersonnelInfoModel> = [];
public get academicPersonelList(): Array<AcademicPersonnelInfoModel> {
return this._academicPersonelList;
}
I have an array that gives teachers information. And i have a list component that lists these teachers. I want to a combobox and filter for this array.
Angular 2+ build in pipes does not support filter pipe like AngularJS. You need to create a custom pipe for filtering to able to do so:
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({name: 'yourTeacherFilter'})
export class ExponentialStrengthPipe implements PipeTransform {
// The pipe's transform method take first Argurment is the data using that pipe( which is data before the '|' mark in the template), the others parameter is optional
transform(input: Array<AcademicPersonnelInfoModel>, lastname, id): number {
// Your logic of returned values go here
return input.filter( x => x.id === id && x.lastName.includes(lastname));
}
}
What the above code does is created a pipe that take an array as the main input along with two additionals paremeter lastname and id. The pipe do the logic you write inside and will return whatever is returned inside the transform() function.
Declare the newly created pipe into your app.module #NgModule() declarations array then you can apply that pipe to your template:
*ngFor= "let account of $data | yourTeacherFilter: search.lastName : search.id"
// The input following `yourTeacherFilter` should match the order
// of parameters you defined inside your custom pipe's transfomrm() function
This is just an simple example pipe for filtering data, you will need further logic to enhance the pipe in your app.
I need a JS tree object in which child nodes know who their parents are. Vue seems OK with this, at least as far as displaying the correct infinitely expandable object in Vue Devtools goes:
... and displaying the correct parent in the console:
The problem is that Vue errors when trying to render that data on a page:
HTML
<ol>
<li>
<b>family.name</b> {{ family.name }}
</li>
<li>
<b>family.children[0].name</b> {{ family.children[0].name }}
</li>
<li>
<b>family.children[1].name</b> {{ family.children[1].name }}
</li>
<li>
<!-- Add the extra brackets to this to see the "object" error -->
<b>family.children[0].parent.name</b> { family.children[0].parent.name }
</li>
</ol>
JS
var app = new Vue({
el: '.container',
data: {
family: {
name: "Dad",
children: [
{
name: "Marcus",
children: [
{
name: "Bob"
}
]
},
{
name: "Anna",
children: [
{
name: "Ringo"
}
]
}
]
}
},
mounted() {
this.family.children[0].parent = this.family;
this.family.children[0].children[0].parent = this.family.children[0];
this.family.children[1].parent = this.family;
this.family.children[1].children[0].parent = this.family.children[1];
}
});
There is a live example if you prefer at https://s3-ap-southeast-2.amazonaws.com/mscau/vue-parenting.htm.
Does anyone know how to overcome this obstacle?
You are setting up that relationship in mounted() lifecycle hook which occurs after the first render, so the render will fail before you even set this up.
If you do this work inside created() hook instead, it will set it up before the first render to avoid the failure.
See lifecycle diagram for more detailed info about these hooks.
I have a react component. I also have a js file that has an array of objects which is imported into the component. I want to use the .map() function on the array and display each piece of information inside li whic is currently inside of the ul that wraps around it. I know the Activity is imported correctly because console.log(Activity) is displaying the 5 items. When it gets to the map function, it is deciding not to iterate and display any of the infromation. I looked at the source code and it just shows an empty unordered list.
import React, { Component } from 'react';
import Activities from '../../../../fakedata/fake_activity';
export default function Activity(props){
console.log(Activities)
return(
<div className="activity-container">
<ul className="activity-list">
{
Activities.map((activity) => {
<li className="activity">
<span className="activity-group">{activity.group}</span>
<span className="activity-date">{activity.date}</span>
<span className="activity-description">{activity.description}</span>
</li>
})
}
</ul>
</div>
)
}
this is the activity object being imported
const activity = [
{
group: 'Homiez',
description: '',
date: '3:22 pm 1/15'
},
{
group: 'Bros',
description: '',
date: '1:48 pm 1/15'
},
{
group: 'Bros',
description: '',
date: '12:31 pm 1/15'
},
{
group: 'Homiez',
description: '',
date: '10:13 am 1/15'
},
{
group: 'Manayek',
description: '',
date: '7:17 pm 1/14'
},
]
module.exports = activity;
You're not returning anything from inside your map function. You either need to change it to be like this:
Activities.map((activity) => {
return (
<li className="activity">
<span className="activity-group">{activity.group}</span>
<span className="activity-date">{activity.date}</span>
<span className="activity-description">{activity.description}</span>
</li>
);
})
or this:
Activities.map((activity) => (
<li className="activity">
<span className="activity-group">{activity.group}</span>
<span className="activity-date">{activity.date}</span>
<span className="activity-description">{activity.description}</span>
</li>
))
This q+a might help you understand why: React elements and fat arrow functions