I have worked on angular 4 project, In this project, I have a requirement to set the first option as selected where all options are created dynamically by loop.
html code:
<select [(ngModel)]="selectedServiceType" [ngModelOptions]="{standalone: true}" (ngModelChange)="getServiceType($event)">
<ng-container *ngFor="let service of services">
<option [ngValue]="service">{{service.name}}</option>
</ng-container>
</select>
If anyone know about let me know. Thanks in advance!
Try like this :
<select class="form-control" (change)="onChange($event)">
<option *ngFor="let service of services; let itemIndex = index" [selected]="itemIndex == 0" [ngValue]="service.value">{{service.name}}</option>
</select>
component.ts
export class HomeComponent implements OnInit {
private selectedServiceType: any;
private services: Array<any> = [];
constructor() {
this.services = [{
name: "Harish",
value: 5000
}, {
name: "Chandru",
value: 5001
}]
}
onChange(e) {
this.selectedServiceType = e.target.value;
}
}
Just in your ts, inside ngOnInit
selectedServiceType : any;
ngOnInit() {
//make sure you have values for **`services`**
this.selectedServiceType = services[0];
}
add this code
<select (change)="onChange($event.target.value)" value={{selectedService}}>
<ng-container>
<option *ngFor="let service of services" >{{service.name}}</option>
</ng-container>
</select>
and you component.ts should be
export class YourClass implements OnInit {
selectedService: any;
services:any = [];
--your API call code set values to services array
this.services=this.service.APImethod()
onChange(newValue) {
this.selectedService=newValue;
}
}
Related
I created a simple reusable component as:
TS
import {Component, Input, OnInit} from '#angular/core';
import {FormControl} from '#angular/forms';
#Component({
selector: 'app-select',
templateUrl: './select.component.html',
styleUrls: ['./select.component.css']
})
export class SelectComponent implements OnInit {
#Input() control: FormControl;
#Input() label: string;
#Input() options: [];
#Input() idAndForAttributes: string;
#Input() customClass: string;
constructor() { }
ngOnInit() {
}
}
HTML
<div class="form-group" [ngClass]="{'invalid': control.invalid && control.touched && control.dirty}">
<label [attr.for]="idAndForAttributes">{{ label }}:</label>
<select class="form-control" [ngClass]="customClass" [formControl]="control" [attr.id]="idAndForAttributes">
<option value="0">- Select -</option>
<option *ngFor="let item of options" [ngValue]="item.id">{{item.description}}</option>
</select>
<ng-container *ngIf="control.dirty && control.touched && control.invalid">
<div *ngIf="control.errors.required || (control.errors.min && control.value == 0)">
<small style="color: #c62828;">
Value is required.
</small>
</div>
</ng-container>
</div>
Now I'm trying to use it in my other html as:
<form [formGroup]="profileActivityForm">
<app-select [control]="profileActivityForm.get('activityType')" [idAndForAttributes]="'type'" [label]="'Type'"
[options]="profileActivityTypes"></app-select>
</form>
Then in TS
profileActivityTypes: string[] = [];
ngOnInit() {
this.profileActivityTypes.push('New')
this.profileActivityTypes.push('Update')
this.profileActivityForm = this.fb.group({
activityType: [0]
});
}
But it is showing invisible options like the following picture:
I think the problem is on the html of the reusable component <option *ngFor="let item of options" [ngValue]="item.id">{{item.description}}</option>
Because it is looking for a description, how can I send the item as a description from the child component?
UPDATE
I tried:
profileActivityTypes: [] = [];
....
let profileActivities = [{ description: 'New' }, { description: 'Update' }]
this.profileActivityTypes.push(profileActivities)
but it is throwing an error on push:
Argument of type '{ description: string; }[]' is not assignable to
parameter of type 'never'
In order to solve this, I changed the assignation of the profileActivities array instead of creating the array and then pushing it. I assign it directly as:
profileActivityTypes = [];
this.profileActivityTypes = [{ id: 1, description: 'New' }, {id: 2, description: 'Update'}]
I hope this works for more people!
A project contains a component and a service.
Component injects the service and uses services field filter. There is a select in the components hmtl. [(ngModel)] of the select is binded to filter.sizes.width.
The component:
#Component({
selector: 'app-facet-sizes-static',
templateUrl: './facet-sizes-static.component.html',
styleUrls: ['./facet-sizes-static.component.scss']
})
export class FacetSizesStaticComponent implements OnInit {
constructor(
private Search: SearchService
) {
this.filter = Search.filter;
}
clearFilter() {
this.filter.sizes.width = 0;
}
}
Its template:
<div (click)="clearFilter()"></div>
<!-- Comment_01 -->
{{filter.sizes.width}}
<div *ngIf="filter.sizes">
<select name="width"
[(ngModel)]="filter.sizes.width">
<option [ngValue]="null">~</option>
<option *ngFor="let item of facet.sizes[0].parts.width; let x = index"
[ngValue]=item>
{{ item }}
</option>
</select>
</div>
The service:
export class SearchService {
filter: SearchServiceFilter = null;
constructor() {
this.filter = {
sizes: {
width: 0
},
};
}
}
When I change option in select it changes filter.sizes.width as I exapt. But there are two problems:
when component is inited there is no value in the select but filter.sizes.width has 0 value. I can check it watching the string {{filter.sizes.width}} under Comment_01
when the method clearFilter() changes filter.sizes.width there is becomes again no value in the select.
How do I solve it?
It sounds like your facet.sizes[0].parts.width array does not contain a value === 0. I see your option with a value of null, but null does not equal 0 and will not be selected. If you add an option with a value === 0; it should select it.
I am using a filter and need to read the value in order to send an API request with the values in the url.
I use this API. I am able to filter both of the categories. After selecting two, we wanna send an API request with both selected values in the url.
We generated a backend-side script to filter, all I need to do is sending a request with the modified url.
app.component.ts
import { Component } from "#angular/core";
import { HttpClient } from "#angular/common/http";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
lines: any[];
filteredLines: any[];
filterBy;
constructor(private http: HttpClient) {}
ngOnInit() {
this.http.get("https://api.mocki.io/v1/26fce6b9").subscribe(lines => {
this.lines = lines;
this.filteredLines = [...this.lines];
});
}
filter() {
this.filteredLines = [
...this.lines.filter(dropdown => dropdown.name.includes(this.filterBy))
];
}
/** Here I need a script onClick button that reads the selected values and sending a get-request of API link above added with the filtered values:
With click on the submit-button, I want to send the API request.
If api.com/data is the link, the request link would be like api.com/data?line=A&workCenter=1
The "?" is for category Line, and "&" for workCenter.
**/
}
}
app.component.html
<select>
<option>Line</option>
<option *ngFor="let dropdown of filteredLines" (keyup)="filter()">
{{dropdown.line}}
</option>
</select>
<select>
<option>Work Center</option>
<option *ngFor="let dropdown of filteredLines" (keyup)="filter()">
{{dropdown.workCenter}}
</option>
</select>
<form action="" method="post">
<input type="submit" name="request" value="Submit" />
</form>
I have created a Stackblitz project for better understanding.
From your example, you need to add [(ngModel)] which will bind to the selected value.
You can find more info on how to properly use a select here More info
<select [(ngModel)]="selectedLine">
<option>Line</option>
<option *ngFor="let dropdown of filteredLines" (keyup)="filter()">
{{dropdown.line}}
</option>
</select>
<select [(ngModel)]="selectedWorkCenter">
<option>Work Center</option>
<option *ngFor="let dropdown of filteredLines" (keyup)="filter()">
{{dropdown.workCenter}}
</option>
</select>
<form action="" method="post">
<input type="submit" name="request" value="Submit" (click)="Submit()" />
</form>
Then in your ts file, declare the select variable and access value as in the click function Submit.
import { Component } from "#angular/core";
import { HttpClient } from "#angular/common/http";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
lines: any[];
filteredLines: any[];
filterBy;
selectedLine; // For first select
selectedWorkCenter; // For second select
constructor(private http: HttpClient) {}
ngOnInit() {
this.http.get("https://api.mocki.io/v1/26fce6b9").subscribe(lines => {
this.lines = lines;
this.filteredLines = [...this.lines];
});
}
filter() {
this.filteredLines = [
...this.lines.filter(dropdown => dropdown.name.includes(this.filterBy))
];
}
requestAnDieAPI() {
console.log(this.filteredLines); // hier muss mein API post request hin
}
Submit() {
var baseUrl = `https://api.mocki.io/`;
var url = `${baseUrl}data?line=${this.selectedLine}&workCenter=${
this.selectedWorkCenter
}`;
this.http.get(url).subscribe(response => {
// response
});
}
}
It is not clear for me if you want to send multiple { line, workCenter } objects to the API call, but from how you setted up the Stackblitz project I will assume you want to send just a single one.
Never seen a (keyup) on an <option> element, use [(ngModel)] on the <select> instead:
<select [(ngModel)]="selected.line">
<option [value]="null">Line</option>
<option *ngFor="let dropdown of filteredLines" [value]="dropdown.line">
{{dropdown.line}}
</option>
</select>
<select [(ngModel)]="selected.workCenter">
<option [value]="null">Work Center</option>
<option *ngFor="let dropdown of filteredLines" [value]="dropdown.workCenter">
{{dropdown.workCenter}}
</option>
</select>
<!-- the use of the form in this case is not required -->
<!-- since you are using requestAnDieAPI to do the api call -->
<form action="" method="post" (submit)="requestAnDieAPI()">
<input type="submit" name="request" value="Submit" />
</form>
<!-- You can also use just a simple button -->
<button (click)="requestAnDieAPI()">Submit</button>
Then your component (model) should contain a selected variable that map the interface (view)
import { Component } from "#angular/core";
import { HttpClient } from "#angular/common/http";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
lines: any[];
filteredLines: any[];
filterBy;
selected = {
line: null,
workCenter: null
};
constructor(private http: HttpClient) {}
ngOnInit() {
this.http.get("https://api.mocki.io/v1/26fce6b9").subscribe((lines: any[]) => {
this.lines = lines;
// this.filteredLines = [...this.lines];
// better:
this.filteredLines = this.lines.slice();
// or either this.filter() directly
});
}
filter() {
// this.filteredLines = [
// ...this.lines.filter(dropdown => dropdown.name.includes(this.filterBy))
// ];
// this is redundant, better:
this.filteredLines = this.lines.filter(dropdown => dropdown.name.includes(this.filterBy))
}
requestAnDieAPI() {
if (this.selected.line != null && this.selected.workCenter != null) {
let apiUrl = "https://api.com/data?line=" + this.selected.line +
"&workCenter=" + this.selected.workCenter
this.http.get(apiUrl).subscribe(/* Your optional response callback/subscriber here */);
}
}
}
I trying to populate a dropdown with my firebase data. I am using angular 9.1.9. Please assist.
category.service.ts
constructor(private db: AngularFireDatabase) { }
getCategories() {
return this.db.list('/categories', (ref) => ref.orderByChild('name'))
.snapshotChanges()
.pipe(
map((actions) => {
return actions.map((action) => ({
key: action.key,
val: action.payload.val(),
}));
})
);
}
product-form.component.html
<select [ngModel] id="category" class="form-control">
<option value=""></option>
<option *ngFor="let c of categories$ | async" [value]="c.key">
{{c.payload.val().name}}
</option>
</select>
products-form-component.ts
export class ProductFormComponent implements OnInit {
categories$;
constructor(categoryService: CategoryService) {
this.categories$ = categoryService.getCategories();
}
{{c.val.name}} would help as your val object already contained payload.val(), just need to access name property from it.
I'm using Angular 7 reactive forms in my component. Part of my component:
#Component({
selector: 'my-form',
templateUrl: './my-form.component.html',
styleUrls: ['./my-form.component.scss']
})
export class MyFormComponent implements OnInit {
form: FormGroup;
loaded: boolean = false;
item: Item;
// item gets loaded from the server and looks like this:
// {
// id: 'dksldfkfjdk',
// title: 'first',
// selected: 'basic'
// }
itemsForSelect = ['basic', 'primary', 'admin'];
isNew: boolean = false;
constructor(private route: ActivatedRoute,
private resourceService: ResourceService,
private fb: FormBuilder,
private router: Router) {
}
ngOnInit() {
this.resourceService.getItem().subscribe(res => {
if (res.success) {
this.item = res.item;
this.createForm();
this.loaded = true;
}
});
}
createForm() {
this.form = this.fb.group({
'title': [this.item.title, Validators.compose([])],
'selected': [this.item.selected, Validators.compose([])]
});
}
}
Part of component HTML template related form:
<form [formGroup]="form" (ngSubmit)="isNew ? create() : update()" [class.error]="!form.valid && form.touched">
<div class="form-group">
<label for="item"></label>
<select placeholder="Choose Select" [formControl]="form.controls.selected" class="form-control"
id="item">
<option *ngFor="let itemForSelect of itemsForSelect">{{ itemForSelect }}</option>
</select>
</div>
<button class="btn btn-primary udpate pointer" [disabled]="!form.valid" type="submit">
{{ isNew ? 'Create' : 'Update' }}
</button>
</form>
The problem is that after updating item with, for example admin value, it has this value from server in property selected, but it still shows basic in HTML select as selected, after fetching data and showing form. How to set selected in Angular 7? I know I can use [(ngModel)] = item.selected, but as I'm using form.controls, I'm getting warning in console.
You can use patchValue on your form control like that:
public updateValue() {
this.form.get('selected').patchValue('basic');
}
Improvement: Dont use formControl with formControlName in same form control. Here is link to deeper explanation
You need to add [value] property to options
<option
[value]="itemForSelect"
*ngFor="let itemForSelect of itemsForSelect"
>{{ itemForSelect }}</option>
Sandbox: https://codesandbox.io/s/angular-l0d09