value of formControl not displayed on view - javascript

I have a form with many fields, It was made with formGroup and formControlName.
The problem is when I start the app I need to get the data from the backEnd and display it on the view.
The problem is that the field Funcion is not displaying the value:
Here is a reduced part of my html code:
<form #f="ngForm" [formGroup]="registros" class="fila-contenido">
<div class="campos">
<!-- En Venta THIS IS OK-->
<label>¿En venta?</label>
<mat-radio-group formControlName="enVenta" aria-labelledby="example-radio-group-label"
class="example-radio-group">
<mat-radio-button value="1" class="example-radio-button">Si</mat-radio-button>
<mat-radio-button value="0" class="example-radio-button">No</mat-radio-button>
</mat-radio-group>
</div>
<!-- Activo THIS IS OK-->
<div class="campos">
<label>¿Registrado?</label>
<mat-radio-group formControlName="activo" aria-labelledby="example-radio-group-label"
class="example-radio-group">
<mat-radio-button value="Si" class="example-radio-button">Si</mat-radio-button>
<mat-radio-button value="En Trámite" class="example-radio-button">En Trámite</mat-radio-button>
<mat-radio-button value="No Necesita" class="example-radio-button">No Necesita
</mat-radio-button>
<mat-radio-button value="No" class="example-radio-button">No</mat-radio-button>
</mat-radio-group>
</div>
<!-- Pais THIS IS OK-->
<mat-form-field appearance="">
<mat-label>Pais</mat-label>
<mat-select formControlName="pais">
<mat-option *ngFor="let pais of selectedPaises" [value]="pais">{{pais}}</mat-option>
</mat-select>
</mat-form-field>
<!-- Funcion THIS IS NOT OK-->
<mat-form-field appearance="">
<mat-label style=" font-weight: bold;">Función</mat-label>
<mat-select formControlName="funcion" required (selectionChange)=changeFuncion($event)>
<mat-option *ngFor="let funcion of funciones" [value]="funcion">{{funcion.Funcion}}
</mat-option>
</mat-select>
</mat-form-field>
</form>
And here is the TS code:
ngOnInit(): void {
this.getRegistros();
}
getRegistros() {
this.http.get<Registro>('http://localhost:7000/api/registros/' + this.service.getRow()).subscribe(data => {
data.log = data.log.replace(/\\"/g, '"');
console.log("formateo", JSON.parse(data.log));
let convert = JSON.parse(data.log);
this.registros.controls.enVenta.setValue(convert.enVenta); //this is OK
this.registros.controls.activo.setValue(convert.activo); //this is OK
this.registros.controls.pais.setValue(convert.pais); //this is OK
this.registros.controls.funcion.setValue(convert.funcion); //this is not OK
});
}
What I've tried:
I've a write a console.log with all the values of the form, the form has all values included the one that is not displayed.
I think it can be related to the ngOnInit problem. But I tried to put getRegistros() on ngAfterViewInit and I was having the same problem :(
Also I tried to use patchValue() instead of setValue() but same problem
Do you have any suggestions?
Thanks.

Angular uses object identity to select option. It's possible for the
identities of items to change while the data does not. This can
happen, for example, if the items are produced from an RPC to the
server, and that RPC is re-run. Even if the data hasn't changed, the
second response will produce objects with different identities.
To overcome this issue we have to provide the compareFn function to mat-select using compareWith input that tells Angular how to compare the values.
Try this:
component.html
<mat-form-field appearance="">
<mat-label style=" font-weight: bold;">Función</mat-label>
<mat-select formControlName="funcion" required (selectionChange)=changeFuncion($event) [compareWith]="compareWithFn">
<mat-option *ngFor="let funcion of funciones" [value]="funcion">{{funcion.Funcion}}
</mat-option>
</mat-select>
</mat-form-field>
component.ts
Here i am assuming your funciones object contains id property.
compareWithFn(listOfItems,selectedItem){
return listOfItems && selectedItem && listOfItems.id === selectedItem.id; ;
}

I think issue is in your template file:
Updated Template:
<mat-form-field appearance="">
<mat-label style=" font-weight: bold;">Función</mat-label>
<mat-select formControlName="funcion" required (selectionChange)=changeFuncion(funcion) [(ngModel)]="funcion">
<mat-option *ngFor="let funcion of funciones" [value]="funcion">{{funcion.Funcion}}
</mat-option>
</mat-select>
</mat-form-field>
Component:
funcion:any;

Related

how to get single selected value from ngx-mat-select-search

How can I get selected value from ngx-mat-select-search and use it on my .ts file?
For example look at this code
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<h3>Single selection</h3>
<p>
<mat-form-field>
<mat-select [formControl]="bankCtrl" placeholder="Bank" #singleSelect>
<mat-option>
<ngx-mat-select-search [formControl]="bankFilterCtrl"></ngx-mat-select-search>
</mat-option>
<mat-option *ngFor="let bank of filteredBanks | async" [value]="bank">
{{bank.name}}
</mat-option>
</mat-select>
</mat-form-field>
</p>
<p>
Selected Bank: {{bankCtrl.value?.name}}
</p>
To display the selected value on the screen we're using bankCtrl.value?.name but how can I implement that in ts file?

mat-autocomplete the option value does not appear correctly in IOS device

When I select the first option in the dropdown, the option is not reflected in the field. When I select the second option then first option value appears and when selects third the second option value appears. Any suggestions as to what the problem is in my code?
This is happening only on iOS devices.Its working fine on Android and Desktop.
emailDomains = AvailableDomains.emailDomains;
export const AvailableDomains = {
emailDomains: [
"hotmail.com",
"gmail.com",
"yahoo.com",
"outlook.com"
]
}
<mat-form-field appearance="outline" class="textbox mat-form-field-invalid">
<span class="iconError icon-alert" aria-hidden="false" aria-label="Error"></span>
<mat-label>Email</mat-label>
<input matInput placeholder="Enter" formControlName="email" type="email" [matAutocomplete]="emailAutoComplete" #email>
<mat-autocomplete #emailAutoComplete="matAutocomplete" panelWidth="auto">
<mat-option *ngFor="let emailDomain of (email.value.endsWith('#') && email.value.split('#').length == 2 ? emailDomains : [])" [value]="email.value + emailDomain">#{{emailDomain}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
I have some auto-complete code that does work on IOS. I compared the two and the difference I see is that I am using (optionSelected) on the mat-autocomplete tag instead of (onSelectionChange) on the mat-option tag. Try it and see.
<mat-form-field appearance="outline" class="textbox mat-form-field-invalid">
<span class="iconError icon-alert" aria-hidden="false" aria-label="Error"></span>
<mat-label>Email</mat-label>
<input matInput placeholder="Enter" formControlName="email" type="email" [matAutocomplete]="emailAutoComplete" #email>
<mat-autocomplete #emailAutoComplete="matAutocomplete" panelWidth="auto" (optionSelected)="updateForm($event,emailDomain)">
<mat-option *ngFor="let emailDomain of (email.value.endsWith('#') && email.value.split('#').length == 2 ? emailDomains : [])" [value]="email.value + emailDomain">#{{emailDomain}}
</mat-option>
</mat-autocomplete>
</mat-form-field>

Angular how to make nested form array act independently

I am trying to solve the problem of having my field change on both form array fields when you change the field type.
As you can see in the image. When I select the left field first name the right field changes to a text field. But when a add a new field it generates a dropdown field to the right and changes the top one as well. How do I make these fields act independently?
I also think the problem is the ngTemplate function I am using to check to see if the field is a option or text field. maybe this is a global within the form I am using, if that makes sense?
Html
<div class="filter-wrapper">
<form [formGroup]="usersForm" (ngSubmit)="onSearch()">
<ng-container *ngFor="let userFormGroup of usersForm.controls.users.controls; let i = index">
<div [formGroup]="userFormGroup" class="filter-form">
<div class="search-wrapper">
<mat-form-field class="form-toggle input-half dialog-dropdown">
<mat-select formControlName="columnOptions">
<mat-option value="null">
-- none --
</mat-option>
<mat-option *ngFor="let formOption of displayedOptions" [value]="formOption.name" (click)="getOptionData(formOption.name)">
{{formOption.title}}
</mat-option>
</mat-select>
</mat-form-field>
<span class="match-txt">matches</span>
<mat-form-field class="input dialog-dropdown">
<ng-container *ngIf="selectedOpt.options?.length > 0; else inputField">
<mat-select formControlName="columnValues">
<mat-option value="null">
-- none --
</mat-option>
<mat-option *ngFor="let formOption of selectedOpt.options" [value]="formOption.display_long_value || formOption.description">
{{ formOption.display_long_value || formOption.description }}
</mat-option>
</mat-select>
</ng-container>
<ng-template #inputField>
<input matInput type="text" formControlName="columnValues">
</ng-template>
</mat-form-field>
</div>
<div class="action-btns">
<mat-icon (click)="addFormControl()">add_circle_outline</mat-icon>
<ng-container *ngIf="i !== 0">
<mat-icon (click)="removeFormControl(i)">remove_circle_outline</mat-icon>
</ng-container>
</div>
</div>
</ng-container>
</form>
</div>
Form builder
this.usersForm = this.fb.group({
users: this.fb.array([
this.fb.group({
columnOptions: ['', Validators.required],
columnValues: ['', Validators.required],
}),
])
})
https://stackblitz.com/edit/angular-l7stwq
The stackblitz wasn't working because the import was missing to initialize columnOption/columnValues, but I think you should reference the formgroups created by your array. I usually start by logging the formgroup.value every step of the way to make sure My ui matches my data model, But try this:
change
<div [formGroup]="userFormGroup" class="filter-form">
to
<div [formGroupName]="i" class="filter-form">
This should match with what your model would be showing for the formArray (since
the groups have index-based names, per them being 'arrays'.
Hopefully this gets you somewhere, If you could update the stackblitz to be able to run I'd do some trial and error to see where I get
Good luck/Happy Coding!

How to increase length of mat-autocomplete and get horizontal scroll

I am running angular, precisely Angular6. I want to increase autocomplete length so I can show many customers and I also want horizontal scroll as customer names are shown only half.
How to achieve this, I did look at the mat-autocomplete documentation I didn't understand much. Any help is really appreciated.
template.html
<mat-form-field [style.cursor]="pointer" [style.cursor]="pointer" [style.width.px]=300 >
<input class="selectCustomer" class="selectCustomerData" id="inputCustomer" matInput [matAutocomplete]="auto" [formControl]="customerFilterControl" [(ngModel)]="customerName">
<mat-icon matSuffix>keyboard_arrow_down</mat-icon>
<p id="spandiv">{{customerName}}</p>
<mat-autocomplete dropdown-arrow="true" panelWidth ="450px" #auto="matAutocomplete" [displayWith] = "displayFn">
<mat-option class="CustomerDropDown" *ngFor="let customer of filteredOptions | async" [value] ="customer.AccountID +' '+'('+ customer.AccountName + ')'" (onSelectionChange)="onCustomerChange(customer)">
{{customer.AccountID}} ({{customer.AccountName}})
</mat-option>
</mat-autocomplete>
</mat-form-field>
template.css
::ng-deep .cdk-overlay-pane {
height:450px;
}
The above effort did not fetch me any result.

Enabling a button using select box

Simply I have two radio buttons when the first radio button is selected one select box appears and when the radio button is selected two select box appears. After this, I have one button "SUBMIT" now I want that when I select first radio then the submit button must be enabled but when I select second radio button then the button must be disabled till both of the select box doesn't have some value.
I am using the form in HTML taking form-group to consider all the fields, when all the fields have some value then the only button will get enabled but in case of the above situation I got stuck.
**This is my javascript code.
I m new in this plz help.**
function statecheck(){
if (document.getElementById('state').checked = true) {
document.getElementById('ifstate').style.display = 'block';
document.getElementById('ifapmc').style.display = 'none';
document.getElementById('ifapmc').disabled = true;
}
}
function stateapmccheck(){
if (document.getElementById('apmc').checked = true) {
document.getElementById('ifapmc').style.display = 'block';
document.getElementById('ifstate').style.display = 'none';
document.getElementById('ifstate').disabled = true;
}
}
This is my Angular material code
<div>
<label>Registration Level: </label>
<mat-radio-group aria-label="Select an option"
formControlName="choosereglevel" #reglevel>
<mat-radio-button value="1" id="state"
onclick="javascript:statecheck();" color="primary">State</mat-radio
button>
<mat-radio-button value="2" id="apmc"
onclick="javascript:stateapmccheck();" color="primary">APMC</mat-radio-
button>
<!--<mat-error
*ngIf="firstFormGroup?.controls?.choosereglevel?.hasError('required')">
Please choose one <strong>level.</strong>
</mat-error>-->
</mat-radio-group>
</div>
<br>
<!--hidden select box-->
<div id="ifstate" style="display:none;">
<mat-form-field>
<mat-label>Registered With State: </mat-label>
<mat-select formControlName="choosestate" #selectstate>
<mat-option *ngFor="let selectstate of registrationstate"
[value]="selectstate.value">
{{selectstate.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<!--second T&C select box-->
<div id="ifapmc" style="display:none;">
<mat-form-field>
<mat-label>Registered With State: </mat-label>
<mat-select formControlName="choosestate" #selectstate>
<mat-option *ngFor="let selectstate of registrationstate"
[value]="selectstate.value">
{{selectstate.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>Registered With APMC: </mat-label>
<mat-select formControlName="chooseapmc" #selectapmc>
<mat-option *ngFor="let selectstate of
registrationapmcstate"
[value]="selectstate.value">
{{selectstate.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
Looks to me like you've got a syntax error inside your if(...) statements
When you use a single = sign it sets the property on the left of it to match the value on the right
To do a comparison you need a double ==
So try document.getElementById('state').checked == true and if document.getElementById('apmc').checked == true

Categories