Angular dependent select boxes doesn't work - json

The first box works well. But the second one doesn't work. They depend on each other. And the error does not appear.
I can't try anything else because it doesn't any errors.
city.service.ts
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class CityService {
constructor(private http:Http) { }
getCitys(){
return this.http.get("http://localhost:3003/api")
.map(response => response.json());
}
}
city.ts
export interface City
{
name: string,
value:number,
down: Down[]
}
export interface Down
{
name: string,
value:number,
places: Places[]
}
export interface Places
{
name: string;
pname:string;
unvan: string
}
city.component.ts
#Component({
selector: 'app-city',
templateUrl: './city.component.html',
styleUrls: ['./city.component.css']
})
export class CityComponent implements OnInit {
cityDatas: [];
downDatas: [];
placesDatas: [];
constructor(private cityService: CityService) { }
ngOnInit() {
this.cityService.getCitys().subscribe(d => {
this.cityDatas = d;
this.downDatas = d.down;
this.placesDatas = d.places });
}
}
city.component.html
<select [(ngModel)]="selectedData">
<option [ngValue]="null" selected disabled>First</option>
<option *ngFor="let data of cityDatas" [value]="data">
{{ data.name }}
</option>
</select>
<select [(ngModel)]="selectedDw" >
<option [ngValue]="null" selected disabled>Second</option>
<option *ngFor="let dw of downDatas" [value]="dw">
{{dw.name}}
</option>
</select>
And api json
[
{"name":"City1",
"value":1,
"down":
[{"name":"Down11",
"value":101,
"places":
[{"name":"Place111",
"pname":"JustPlace",
"unvan":"center"
},
{"name":"Place112",
"pname":"Jp",
"unvan":"center"
}]
},
{"name":"Down12",
"value":102,
"places":
[{"name":"Place121",
"pname":"Jp",
"unvan":"side"
},
{"name":"Place122",
"pname":"Jp",
"unvan":"side"
}]
}
]
},
{"name":"City2",
"value":2,
"down":
[{"name":"Down21",
"value":103,
"places":
[{"name":"Place211",
"pname":"Jp",
"unvan":"center"
},
{"name":"Place212",
"pname":"Jp",
"unvan":"center"
}]
},
{"name":"Down22",
"value":104,
"places":
[{"name":"Place221",
"pname":"JustPlace",
"unvan":"side"
},
{"name":"Place222",
"pname":"Jp",
"unvan":"side"
}]
}
]
}
]
When I choose the first one, I want the second to work. And I want the results displayed. But I couldn't run the second select box and the console didn't give any errors.
Why does not work? And how will it work?

downDatas is undefined, because d in the subscription is an array, not an object. Try to implement it in this way (after selecting selectedData in the first select, this data will be available in the second):
<select [(ngModel)]="selectedData">
<option selected disabled>First</option>
<option *ngFor="let data of cityDatas; index as i;" [value]="i">
{{ data.name }}
</option>
</select>
<select [(ngModel)]="selectedDw" >
<option [ngValue]="null" selected disabled>Second</option>
<option *ngFor="let dw of cityDatas[selectedData]?.down" [value]="dw">
{{ dw.name }}
</option>
</select>
stackblitz

You need implement change event of city select tag and update datasource for downDatas
onChange($event, cityid) {
let selectedcity = this.cityDatas.filter(c=>c.value == cityid)[0];
console.log(JSON.stringify(selectedcity))
this.downDatas = selectedcity.down;
}
HTML
<select [(ngModel)]="selectedData" #city (change)="onChange($event, city.value)">
Demo https://stackblitz.com/edit/angular-city-down?file=src/app/app.component.ts

Related

Displaying objects dropdown from an array - Angular

I need help with this implementation. Im have an array loaded with some objects, and i want to display only the property called "name" of those objects in the dropdown, and when i select one of those options, i want to have access to the entire object. Is that possible?
At the moment i tried this code:
HTML of the component:
<select (change)="update($event)">
<option value="default">----</option>
<option value={{item}} *ngFor="let item of noMensuales">
{{item.nombre}}
</option>
</select>
TS of the component:
import { Component, OnInit } from '#angular/core';
import { ServicesDebCredService } from 'src/app/services/services-deb-cred.service';
#Component({
selector: 'app-pago-no-mensual',
templateUrl: './pago-no-mensual.component.html',
styleUrls: ['./pago-no-mensual.component.css']
})
export class PagoNoMensualComponent implements OnInit {
noMensuales: any = []
seleccionado:any = {}
constructor(private _serviceDebCred: ServicesDebCredService) { }
update(e : any) {
this.seleccionado = e.target.value
console.log(this.seleccionado)
console.log(this.seleccionado.nombre)
}
ngOnInit(): void {
this.getNoMensuales()
}
getNoMensuales() {
this._serviceDebCred.getNoMensuales().subscribe((res) => {
this.noMensuales = res.noMensuales
})
}
}
The thing is that, on the "seleccionado" field (the one i want to select and get the entire object) i have an empty object when i click on one of the list...
Yes it is possible, you need to tweak your code little bit, If you have an ID in your object just refer that pass that ID as value.
HTML file
<select (change)="update($event)">
<option value="default">----</option>
<option value={{item.id}} *ngFor="let item of noMensuales">
{{item.nombre}}
</option>
</select>
TS file: Into your update function:
update(e : any) {
let selectedObject = {};
this.noMensuales.map((res)=>{
if(e.target.value == res.id){
selectedObject = res;
}
});
console.log(selectedObject)
}
If you dont have ID or unique values in your object you can do it with ngFor index as well
You can easily access the object by referring this.
<select (change)="update($event)">
<option value="default">----</option>
<option value={{item}} *ngFor="let item of noMensuales">
{{item.nombre}}
</option>
I have reduced your update function code line for get your response very quickly
update(e : any) {
console.log(this.noMensuales.filter(item => item.id === e.target.value)[0])
}

Angular CLI disable html form if previous option not selected?

I have a form that has a few select fields populated with options.
<form [formGroup]="selectVehicleForm">
<select formControlName="Manufacturer">
<option *ngFor='let cars of cars$'>{{cars.Manufacturer}}</option>
</select>
<select formControlName="Model">
<option *ngFor='let cars of cars$'>{{cars.Model}}</option>
</select>
</form>
My question - how can I disable my "Model" field as long as a user has nothing selected in "Manufacturer"?
You can try like this (not tested) :
constructor(private fb: FormBuilder) {
this.selectVehicleForm = this.fb.group({
Manufacturer: [],
Model: [{ value: '', disabled: true }]
)};
this.selectVehicleForm.get('Manufacturer').valueChanges.subscribe(value => {
if (value) {
this.selectVehicleForm.get('Model').enable();
} else {
this.selectVehicleForm.get('Model').reset('');
this.selectVehicleForm.get('Model').disable();
}
this.selectVehicleForm.updateValueAndValidity();
})
}
You can listen (change) on the FormControl Manufacturer and call enable()/disable() on the FormControl Model
See the Stackblitz
Relevant parts are :
HTML
<select formControlName="Manufacturer" (change)="onChangeManufacturer($event)">
<option *ngFor='let cars of cars$'>{{cars.Manufacturer}}</option>
</select>
Typescript
selectVehicleForm = new FormGroup({
Manufacturer: new FormControl(),
Model: new FormControl(),
});
ngOnInit() {
this.selectVehicleForm.controls['Model'].disable();
}
onChangeManufacturer(value) {
const formControlModel = this.selectVehicleForm.controls['Model'];
if(this.selectVehicleForm.controls['Manufacturer']) {
formControlModel.enable();
} else {
formControlModel.disable();
}
}

How to get selected value of dropdown in angular 6 on load(not onchange)

I have a select dropdown ,I am getting option's data and value from an array through loop. Here I need to get the value of selected drop down when page loads without onchange(in this case Recent). Here is code below.
app.component.html
<select>
<option *ngFor="let v of values" [value]="v.id">
{{v.name}}
</option>
</select>
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
title = 'projectchart';
public values = [
{ id: 3432, name: "Recent" },
{ id: 3442, name: "Most Popular" },
{ id: 3352, name: "Rating" }
];
ngOnInit(){
alert('The default selected value is');
}
}
you could make use of reactive forms
constructor(private fb: FormBuilder) { }
// create a form group using the form builder service
formName = this.fb.group({
name: ['']
})
in the template
<form [formGroup]="formName">
<select formControlName="name">
<option *ngFor="let v of values" [value]="v.id">
{{v.name}}
</option>
</select>
</>
and then get the value in the ts:
this.formName.controls['name'].value

Default selected checkbox

I want to ask about how I can set option to be default selected?
<form [formGroup]="form2">
<select formControlName="drop">
<option disabled>Choose one</option>
<option *ngFor="let example of examples" [value]="example.id" [disabled]="example.isDisabled" [selected]="example.isSelected">{{ example.name }}</option>
</select>
</form>
Component:
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormControl, Validators } from '#angular/forms';
#Component({
selector: 'app-drop-down-list',
templateUrl: './drop-down-list.component.html',
styleUrls: ['./drop-down-list.component.css']
})
export class DropDownListComponent implements OnInit {
public form = new FormGroup({
drop: new FormControl('',
Validators.required,
),
});
public form2 = new FormGroup({
drop: new FormControl('',
Validators.required,
),
});
examples = [{
id: 1, name: 'Test1', isSelected: false, isDisabled: true,
},
{
id: 2, name: 'Test2', isSelected: true, isDisabled: false,
},
{
id: 3, name: 'Test3', isDisabled: false,
}
];
constructor() { }
ngOnInit() {
}
onSubmit(form) {
console.log(form);
}
}
I was searching on stack but I don't want to mix reactive forms with ngModel, also I don't wan't to use patchValue because It only set default value without choosing element in list. Thanks for help!
if you want option to be selected then do like this , just pass id value in your formcontrol intialization
public form2 = new FormGroup({
drop: new FormControl(this.examples[0].id,
Validators.required,
),
});
or if you dont want to initialization immediately and want later on then make use of setValue method, below is required when you are fecthing data from server and want to set value i just hard coded value just to show as example , you should replace with the value you get from server
form2.get('drop').setValue('1');
html should be as below no need of [selected]
<select formControlName="drop">
<option disabled>Choose one</option>
<option *ngFor="let example of examples" [value]="example.id" [disabled]="example.isDisabled" >{{ example.name }}</option>
</select>

Select Option Filter in Angular 4 with pipe

I am trying to create a pipe with the selectbox dropdown for filtering the list in json data. I have created a pipe with selectbox pipe. I am not able to get my filter work in pipe. Please help. Here is my code -
Select Box -
<select class="form-control" [(ngModel)]="sel" name="sel">
<option selected disabled>Select</option>
<option *ngFor="let positionOpt of positionSelect" [value] = "sel">{{positionOpt.name}}</option>
</select>
Data For SelectBox Options Field -
positionSelect:any[] = [
{
name: "Social Media Manager",
position: "Social Media Manager"
},
{
name: "Product Manager",
position: "Product Manager"
}
]
Pipe for selectbox -
import { Pipe, PipeTransform } from '#angular/core';
import { JobsService } from '../services/jobs.service';
#Pipe({
name: 'selectbox'
})
export class SelectboxPipe implements PipeTransform {
transform(opt: any, sel?: any): any {
return (opt || opt === '0')
? opt.filter(sal => { return sal.position == sel})
: opt;
}
}
Job List Data -
<ul class="jobs-list">
<li *ngFor="let joblists of jobList | selectbox: sel">
{{joblists.position}}
</li>
</ul>
This jobList data in Json is coming from a service. Should I use *ngFor in select option field from jobList or it is fine coming from different json data. Please help with selectbox filter.
Try this:
import { Pipe, PipeTransform } from '#angular/core';
import { JobsService } from '../services/jobs.service';
#Pipe({
name: 'selectbox'
})
export class SelectboxPipe implements PipeTransform {
transform(items: any, sel?: any): any {
return sel ? items.filter(sal => sal.position === sel) : items;
}
}
<select class="form-control" [(ngModel)]="sel" name="sel">
<option *ngFor="let positionOpt of positionSelect" [ngValue]="positionOpt.position">{{positionOpt.name}}</option>
</select>
<ul class="jobs-list">
<li *ngFor="let joblists of jobList | selectbox: sel">
{{joblists.position}}
</li>
</ul>
Try this :
I got sel value which object you selected in dropdown list. that values is show in selectbox.pipe.ts console.log
app.component.html
<select class="form-control" name="sel" id="sel" [(ngModel)]="sel">
<option [ngValue]="undefined" disabled selected>Select...</option>
<option *ngFor="let positionOpt of positionSelect" [ngValue]="positionOpt">{{positionOpt.name}}</option>
</select>
<ul class="jobs-list">
{{sel}}
<li *ngFor="let joblists of jobList | selectbox: sel">
{{joblists.position}}
</li>
</ul>
app.component.ts
export class AppComponent {
private sel: any;
private jobList: any[];
private positionSelect: any[] = [{
name: "Social Media Manager",
position: "Social Media Manager"
},
{
name: "Product Manager",
position: "Product Manager"
}]
}
selectbox.pipe.ts
import { Component, NgModule, Pipe, PipeTransform } from '#angular/core'
import { BrowserModule } from '#angular/platform-browser'
#Pipe({
name: 'selectbox'
})
export class SelectboxPipe implements PipeTransform {
transform(opt: any, sel?: any): any {
console.log('sel', sel);
return (opt || opt === '0') ? opt.filter(sal => { return sal.position == sel }) : opt;
}
}
app.module.ts
import { SelectboxPipe } from './selectbox.pipe';
#NgModule({
declarations: [
SelectboxPipe
],
exports: [
SelectboxPipe
]
})