How to display array item in Angular - html

I am a newbie in Angular, I create an array but I have problem to display it.
When I display the array item it is blank.
write.component.html:
<div class="data">
<li> Name: <input type="text" [(ngModel)]="name" placeholder="Please enter Name" ></li>
<li> Age:<input type="text" [(ngModel)]="age" placeholder="Please enter Age" class="age"></li>
<li>College:<input type="text" [(ngModel)]="college" placeholder="Please enter College" ></li>
</div>
<h2>Student</h2>
<ul class="details">
<li>
<span class="badge" *ngFor="let student of students"> // display array item
{{student.name}}{{student.age}}{{student.college}}</span>
</li>
</ul>
.ts
export class WriteComponent implements OnInit {
name : string;
age : number;
college : string;
students : Array<any>; // declare array
}
write-service.ts
import { Injectable } from "#angular/core";
#Injectable()
export class HomeService {
private students = new Array<any>( //array details
{
name:"dwq",
age:12,
college:"2321"
}
)
}

After you create the service you have to inject that service to your component like this
constructor(private homeServ:HomeService) { }
then the service will be avilable in the componnet you can get the data
ngOnInit(){
this.students = this.homeServ.getStudents();
}
demo πŸš€
you can remove the injectable decorator from the service if the service has no dependency
read more about angular services πŸ‘‰ her

Related

How to pass value from one component to another? (Angular)

I just recently started learning Angular and I have a question. I want to implement a search method to search for a product on my site, I made search.pipe.ts, which works, but the input for input is in the header.component.ts component, and the products array is in the car-list.component.ts component.
car-list.component.html
<div *ngFor="let car of cars | paginate: { itemsPerPage: pageNumber, currentPage: currentPg} | **search:searchStr**" class="col-md-3">
<div class="product box">
<img src="{{'data:image/jpg;base64,' + car.image }}" alt="">
<h3>{{ car.name }}</h3>
<div class="price">{{ car.price | currency:'USD' }}</div>
<button class="btn btn-primary btn-sm">Add to cart</button> <!--(click)="addToCart(tempProduct)"-->
</div>
<br>
</div>
header.component.html
<form class="d-flex me-5">
<input type="text" class="form-control me-2" placeholder="Search cars...">
</form>
header.component.ts
export class HeaderComponent implements OnInit {
searchStr: string = '';
constructor() {
}
ngOnInit(): void {
}
}
search.pipe.ts
#Pipe({
name: 'search'
})
export class SearchPipe implements PipeTransform {
transform(cars: any[], value: any) {
return cars.filter(car => {
return car.name.includes(value);
})
}
}
I want the input values ​​from the header component to be passed to the car-list component so that I can find the product I need.
In this case you can use a shared service where you can pass data from your header component and load that data in your products component.
For further reference - Angular 4 pass data between 2 not related components
use #Input and #Output decorators to communicate between components

How to set value to 2d array in input tag html

I am work in angular. I would like the user to be able to set up lesson subjects and a specific number of hours for a given student group.
group.component.html:
<!--list of groups -->
<div *ngFor="let group of groups">
<div><button (click)="Edit()">Edit group</button></div>
<!--mode without edit -->
<div *ngIf="edit==false">
<tr>Name:{{group.name}}</tr>
</div>
<!--mode with edit -->
<div *ngIf="edit==true">
<tr>Name:<input type="text" value="{{group.name}}" [(ngModel)]="group.name m[ngModelOptions]="{standalone: true}"></tr>
<!--add Subject and set amount hours -->
<!-- add one or more empty subject, select subject and set amount hours-->
<tr>Subjects:</tr>
<button (click)="addSubject()">add</button>
<!-- list of subjects for one group-->
<form>
<div *ngFor="let sub of yourSubjects; let i=index">
<select class="form-control">
{{group.name}}
<option *ngFor="let sub2 of subjectsList" value="{{sub2.name}}">{{sub2.name}}</option>
<input type="hide" [(ngModel)]="groupItem.subjects[[i][0]]" [ngModelOptions]="{standalone: true}">
</select>
<!-- set amount hours for one subject -->
<!--kind of lessons, for one subject -->
Lecture(h)<input type="text" [(ngModel)]="groupItem.subjects[[i][1]]" [ngModelOptions]="{standalone: true}">
workout(h)<input type="text" [(ngModel)]="groupItem.subjects[[i][2]]" [ngModelOptions]="{standalone: true}">
laboratory(h)<input type="text" [(ngModel)]="groupItem.subjects[[i][3]]" [ngModelOptions]="{standalone: true}">
<button (click)="deleteSubject()">Delete</button>
</div>
<!--send data to function -->
<input type="submit" value="Submit" (click)="Edit();updateGroup({id : group.id, name : group.name, yourAllSubjects : groupItem.subjects})">
</form>
</div>
</div>
group.component.ts:
import { Component, OnInit } from '#angular/core';
import {GroupsApiService, RoomsApiService, SubjectsApiService} from "../../../api.services";
import {Groups} from "../../../models/groups.model";
import {Subjects} from "../../../models/subjects.model";
#Component({
selector: 'app-group',
templateUrl: './group.component.html',
styleUrls: ['./group.component.css']
})
export class GroupComponent implements OnInit {
constructor(private groupsApiService:GroupsApiService, private subjectsApiService: SubjectsApiService) { }
groups:Groups[] = [] //list of groups from database
subjectsList:Subjects[]=[] //list of all subjects
groupItem:Groups = new Groups('',1) //one group object
subject:Subjects = new Subjects('',1) // one subject object
number:number = history.state?.data?.title // index one group from groups.component
ngOnInit(): void {
this.groupsApiService.getGroup(this.number).subscribe(data => this.groups = data);
this.subjectsApiService.getSubjects().subscribe(data=>this.subjectsList=data);
// get data from database, data of one group, data of subjects, function from apiservice
}
yourSubjects: Subjects[]=[]; //list of subject for one group
edit=false //say when edit mode on/off
//edit mode
Edit() {
this.edit = !this.edit;
}
// function in html, it send data to database
updateGroup({id, name, yourSubjects}: { id: number, name: string, yourAllSubjects: [][] }){
var arrStr = encodeURIComponent(JSON.stringify(yourSubjects));
this.groupsApiService.editGroup(id,name,arrStr).subscribe()
}
addSubject() {
this.yourSubjects.push(this.subject)
}
deleteSubject(){
this.yourSubjects.pop()
}
}
group.model.ts
export class Groups {
constructor(
public name: string,
public id: number,
public subjects:[][]
) { }
}
apiservice
#Injectable()
export class GroupsApiService {
constructor(private http: HttpClient) {
}
getGroups(): Observable<Groups[]> {
return this.http.get<Groups[]>(`${API_URL}/management/groups`)
}
editGroup(id:number,name: string, yourSubjects?:string){
return this.http.get<Groups[]>(`${API_URL}/management/groups/group/editgroup?id=${id}&name=${name}&subjects=${yourSubjects}`)
}
getGroup(id:number): Observable<Groups[]> {
return this.http.get<Groups[]>(`${API_URL}/management/groups/group?id=${id}`)
}
}
Summary:
The user selects one group and can edit it. He can add specific subjects to it, then specify the number of hours for the types of lessons in a given subject. The number of hours is specified in three text inputs. Then the array saves itself. The array is to keep the names of the items and the individual hours. e.g:
groupItem.subjects[[i][0]]= physics
groupItem.subjects[[i][1]] = 11
groupItem.subjects[[i][2]] = 12
groupItem.subjects[[i][3]] = 30
groupItem.subjects = [{'physics','11','20','30'},{'math','11','20','30'},{'biology','11','20','30'}]
In html have function:
```
<input type="submit" value="Submit" (click)="Edit();updateGroup({id : group.id, name : group.name, yourAllSubjects : groupItem.subjects})">
and in groyp.component.ts:
```
updateGroup({id, name, yourSubjects}:{ id: number, name: string, yourAllSubjects: string[][] })
{ var arrStr = encodeURIComponent(JSON.stringify(yourSubjects)); this.groupsApiService.editGroup(id,name,arrStr).subscribe()
}
Next url is send to backend. Unfortunalety i have null in subject:
http://localhost:5000/management/groups/group/editgroup?id=6&name=example&subjects=[]'
what to do to send arrays correctly in url?

How to use *Ngfor in an other *Ngfor

I am trying to create a checkbox for each element of an array "lesCriteres".
Then I want each of these checkboxes to be checked if its value is in the table "actif.lesCriteresActifs"
Here is the code I want but it does not work as I want
<div class="checkbox-inline" *ngFor="let l of lesCriteres">
<div *ngFor="let a of actif.lesCriteresActifs">
<label></label>
<input type="checkbox" (change)="onChangeEvent(l.code, $event.target.checked)" [checked]="a.critere.code==l.code"> {{l.code}}<br>
</div>
</div>
MODELS
actif model
import {TypeActif} from './model.type-actif';
import {CritereActif} from './model.critere-actif';
export class Actif{
ref: string;
nom: string = '';
type_actif: TypeActif = new TypeActif();
lesCriteresActifs: Array<CritereActif> = new Array<CritereActif>();
}
CritereActif model
import {Actif} from './model.actif';
import {LesCriteres} from './model.les-criteres';
import {LesValeurs} from './model.les-valeurs';
export class CritereActif{
id: number;
actif: Actif = new Actif();
critere: LesCriteres = new LesCriteres();
valeur: LesValeurs = new LesValeurs();
}
LesCriteres model
export class LesCriteres{
code: string = null;
nom: string = '';
}
RESULT
i have this when i execute my code :
but i want't something like this :
This should work (using includes() method, without additional *ngFor):
<div class="checkbox-inline" *ngFor="let l of lesCriteres">
<label></label>
<input type="checkbox" (change)="onChangeEvent(l.code, $event.target.checked)" [checked]="actif.lesCriteresActifs.includes(l)"> {{l.code}}<br>
</div>
About includes method: https://www.w3schools.com/jsref/jsref_includes_array.asp
EDIT:
This solution comes to mind.
In .ts file of your component, inside class declare a function:
containsCode = (code) => {
for (let a of this.actif.lesCriteresActifs) {
if (a.critere.code === code) {
return true
}
}
return false
Then in .html file:
<div class="checkbox-inline" *ngFor="let l of lesCriteres">
<label></label>
<input type="checkbox" (change)="onChangeEvent(l.code, $event.target.checked)" [checked]="containsCode(l.code)"> {{l.code}}<br>
</div>

Uncaught Error: Can't resolve all parameters for Component: ([object Object]?)

So, before You read the whole error stack, keep in mind that at this time I cant pinpoint the exact piece that causes the problem. However, I will disclose the code below the error stack. So, my only question is: what parameters can't be resolved?
If you like, you can test my application for yourself. It is a simple default angular 6 application with all the default settings you get from the following command below:
ng new app-name
let's begin with the error. The application starts like normal. When I try to run the code, this error pops up: Uncaught Error: Can't resolve all parameters for Component: ([object Object]?). You can read the full error stack below.
Uncaught Error: Can't resolve all parameters for Component: ([object Object]?).
at syntaxError (compiler.js:1016)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getDependenciesMetadata (compiler.js:10917)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getTypeMetadata (compiler.js:10810)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNonNormalizedDirectiveMetadata (compiler.js:10429)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.loadDirectiveMetadata (compiler.js:10291)
at compiler.js:23865
at Array.forEach (<anonymous>)
at compiler.js:23864
at Array.forEach (<anonymous>)
at JitCompiler.push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler._loadModules (compiler.js:23861)
syntaxError # compiler.js:1016
push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getDependenciesMetadata # compiler.js:10917
push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getTypeMetadata # compiler.js:10810
push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNonNormalizedDirectiveMetadata # compiler.js:10429
push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.loadDirectiveMetadata # compiler.js:10291
(anonymous) # compiler.js:23865
(anonymous) # compiler.js:23864
push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler._loadModules # compiler.js:23861
push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler._compileModuleAndComponents # compiler.js:23839
push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler.compileModuleAsync # compiler.js:23799
push../node_modules/#angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js.CompilerImpl.compileModuleAsync # platform-browser-dynamic.js:143
push../node_modules/#angular/core/fesm5/core.js.PlatformRef.bootstrapModule # core.js:4352
./src/main.ts # main.ts:11
__webpack_require__ # bootstrap:76
0 # main.ts:12
__webpack_require__ # bootstrap:76
checkDeferredModules # bootstrap:43
webpackJsonpCallback # bootstrap:30
(anonymous) # main.js:1
As you see, there is no easy way of telling which part of my typescript is causing the problem. However, The application runs fine without the code in component.ts shown below. So, there is definitely something wrong with my typescript component.ts
the component.ts is shown below:
import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild, Directive} from '#angular/core';
import { FormGroup } from '#angular/forms';
import { DefineBusinessRuleService } from '../services/define/define-business-rule.service';
import { DefineBusinessRuleNamespace } from '../model/business-rule-namespace';
#Component({
selector: 'app-define-business-rule',
templateUrl: './define-business-rule.component.html',
styleUrls: ['./define-business-rule.component.css']
})
export class DefineBusinessRuleComponent implements OnInit {
// interfaces
headers : Headers;
output: any;
#Input() minValue: string;
#Input() maxValue: string;
#Input() attribute : Array<string>;
#Input() table : Array<string>;
submitted = false;
#Input() businessRuleType : Array<string>;
ruletypes : Array<string>;
ruletype : string;
constructor(
private defineBusinessRuleService: DefineBusinessRuleService
,private model : any
) {
this.table = ['table1', 'table2', 'table3'];
this.attribute = ['attribute1', 'attribute2', 'attribute3'];
this.ruletypes = [
// atrribute
'AttributeRange',
'AttributeCompare',
'AttributeList',
'AttributeOther',
'TupleCompare',
'TupleOther'
]
model = {
minValue : 5,
maxValue : 10,
name : 'RangeRule',
description : 'This is a Range Rule',
table1 : this.table[0],
column1 : this.attribute[2],
errorMsg : 'Error message'
};
}
get diagnostic() { return JSON.stringify(this.model); }
defineNewBusinessRule() {
//this.model = new DefineBusinessRuleService(42, 50, '', '', '', '', '');
}
saveAttributeRangeRule(){
this.output = {
database_id : 1,
minValue : this.minValue,
maxValue : this.maxValue,
table1 : this.table,
column1 : this.attribute
}
this.output.stringify;
this.defineBusinessRuleService.saveAttributeRangeRule(this.output);
}
saveAttributeCompareRule(){
this.output = {
database_id : 1,
table1 : this.table,
//table2 : this.table2,
column1 : this.attribute,
//column2 : this.attribute2,
//value : this.value
}
this.output.stringify;
//this.defineBusinessRuleService.saveAttributeCompareRule(this.output);
}
ngOnInit(){
}
onSelect(){
}
onSubmit() {
this.submitted = true;
this.ruletype = this.ruletypes[0];
switch(this.ruletype){
case "AttributeRange" : {
this.saveAttributeRangeRule();
break;
};
case "AttributeCompare" : {
this.saveAttributeCompareRule();
break;
};
}
}
}
Thanks for reading this! If you are visually orientated like me, then this form might help you understand what this code should do. However, it's off topic, since i'm certain enough that it doesn't cause operational problems in angular. keep that in mind!
the related html form is shown below
<br>
<br>
<main role="main" class="container">
<div class="container">
<h1>Define Business Rule</h1>
<form (ngSubmit)="onSubmit()" #defineBusinessRuleForm="ngForm">
<div class="form-group">
<label for="minValue">Minimum Value</label>
<input type="text" class="form-control" id="minValue">
</div>
<div class="form-group">
<label for="maxValue">Maximum Value</label>
<input type="text" class="form-control" id="maxValue">
</div>
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name"
#name="ngModel">
<div [hidden]="name.valid || name.pristine"
class="alert alert-danger">
Name is required
</div>
</div>
<div class="form-group">
<label for="description">Description</label>
<input type="text" class="form-control" id="description" required>
</div>
<div class="form-group">
<label for="table">Table</label>
<select class="form-control" id="table" required>
<option *ngFor="let tbl of table" [value]="table">{{tbl}}</option>
</select>
</div>
<div class="form-group">
<label for="attribute">Attribute</label>
<select class="form-control" id="attribute" required>
<option *ngFor="let attr of attribute" [value]="attribute">{{attr}}</option>
</select>
</div>
<div class="form-group">
<label for="errorMsg">Error Message</label>
<input type="text" class="form-control" id="errorMsg" required>
</div>
<button type="submit" class="btn btn-success" [disabled]="!defineBusinessRuleForm.form.valid">Submit</button>
<button type="button" class="btn btn-default" (click)="defineNewBusinessRule(); defineBusinessRuleForm.reset()">Define New BR</button>
</form>
</div>
</main>
The error is in the model definition location.
private model: any should be defined as a parameter outside of a constructor.
By placing it in the constructor, the compiler is trying to resolve any class, and, naturally is unable to do so.
Modify your code this way:
export class DefineBusinessRuleComponent implements OnInit {
private model : any
constructor() {
this.model = {
// your model definition
};
}
// rest of the code
}

angular 4 Drop Down Menu Setting Selected State

Hi I am working on an angular 4 web app. I am trying to set the initial selected state of a drop down menu. No matter what I do though the initial selected state of the drop down menu is not being set. See my html below ( am trying to set the healthy option of a recipe to either be 'yes' or 'no', depending what is brought back from the database:-
<div class="row">
<div class="col-md-12">
<form [formGroup]="update_recipe_form" (ngSubmit)="createUpdateRecipeIngredientsDetailsForm()">
<table class="table table-hover table-responsive table-bordered">
<tr>
<td>
Healthy
</td>
<td><!--<li *ngIf="recipe?.healthy == 'Yes'"><h4><i class='fa fa-heart' aria-hidden='true'></i>Healthy</h4></li>-->
<select name="isHealthy" formControlName="isHealthy" class="form-control" required>
<option *ngFor="let healthy of healthyOptionsArray" [selected]="isHealthy==healthy.state" value="{{healthy.id}}">
{{healthy.state}}
</option>
</select>
<div *ngIf="update_recipe_form.get('isHealthy').touched && update_recipe_form.get('isHealthy').hasError('required')"
class="alert alert-danger">Select whether recipe is healthy
</div>
</td>
</tr>
<tr>
<td></td>
<td>
<button class="btn btn-primary" type="submit" [disabled]="update_recipe_form.invalid">
<span class="glyphicon glyphicon-edit"></span> Update
</button>
</td>
</tr>
</table>
</form>
</div>
</div>
Typescript module code:-
import { Component, Output, Input, EventEmitter, OnChanges, ElementRef } from '#angular/core';
import { FormGroup, FormControl, Validators, FormBuilder } from '#angular/forms';
import { RecipeService } from '../recipe.service';
import { Recipe } from '../recipe';
import { Healthy } from '../healthy';
#Component({
selector: 'app-update-recipe',
templateUrl: './update-recipe.component.html',
styleUrls: ['./update-recipe.component.css'],
providers: [RecipeService, CategoryService, DifficultyService, ImageService, IngredientService, IngredientDetailService ]
})
export class UpdateRecipeComponent {
#Output() show_read_recipes_event = new EventEmitter();
#Input() recipe_id;
update_recipe_form: FormGroup;
healthyOptionsArray = [
new Healthy(0, 'no'),
new Healthy(1, 'yes')
]
constructor(private _recipeService: RecipeService,
private formBuilder: FormBuilder,
private elem: ElementRef
)
{
// build angular form
this.update_recipe_form = this.formBuilder.group({
recipe_name: ["", Validators.required],
recipe_id: '',
isHealthy: ["", Validators.required],
});
}
readRecipes(){
this.show_read_recipes_event.emit({ title: "Read Recipes"});
}
ngOnChanges(){
this._recipeService.readOneRecipeForUpdate(this.recipe_id)
.subscribe(
recipe => {
console.log(recipe);
this.update_recipe_form.patchValue({
recipe_name: recipe.recipe_name,
recipe_id: recipe.recipe_id,
isHealthy: recipe.healthy,
});
}
);
}
This is the Healthy class code:-
export class Healthy{
constructor(
public id: number,
public state: string
)
{}
}
Hope somebody can put me out of my misery (I have been stuck on this one for a few days now).
If you're setting object value exactly same that of healthy object of iterator, then use ngValue directive to bind whole object value to form. It will help to pre-populate value.
<select name="isHealthy" formControlName="isHealthy" class="form-control" required>
<option *ngFor="let healthy of healthyOptionsArray" [ngValue]="healthy">
{{healthy.state}}
</option>
</select>
You can change:
[selected]="isHealthy==healthy.state"
to:
[selected]="healthy.state === 'yes'"
This worked:
<select name="isHealthy" formControlName="isHealthy" class="form-control" required>
<option *ngFor="let healthy of healthyOptionsArray" [selected]="healthy.state == isHealthy">
{{healthy.state}}
</option>
</select>