2

We have list like below ( in original implementation productList will come from API )

productList = [{
    productId: "104",
    productName: "computer"
  },
  {
    productId: "105",
    productName: "Sprots"
  },
  {
    productId: "106",
    productName: "TV"
  }];

we need to display product name as radio buttons in html, something like this.

[] Computer
[] Sports
[] TV

and when we select one radio button it should give selected item in component ( for example if we select TV radio button then, may be something like this ?

this.myForm.controls['productMethods'].valueChanges.subscribe(value => {
      var a  = value 
      // how can i get a = { productId: "106",productName: "TV"} **?**
    }

for pre selected :-

[] Computer
[x] Sports <== how to make sports as pre-selected on page load also **?**
[] TV

what i have tried is https://stackblitz.com/edit/angular-formarray-example-2-3xq45k but failed to display radio buttons.

Thanks,

3
  • you link is not working and you have made mistake in *ngFor and also add formArrayName in your template Commented Jan 9, 2019 at 15:45
  • @Abhishek - sure, i will update the link Commented Jan 9, 2019 at 16:23
  • @Abhishek - updated. Commented Jan 9, 2019 at 16:25

3 Answers 3

3

Here is an updated version of your Stackblitz.

First, since you are using radio inputs, you are only going to receive a single value, not an array.

this.productFormGroup = this.formBuilder.group({
  productMethod: new FormControl("105"),
});

Second, your radio inputs need to all have the same name (that name needs to match the formControlName).

<input type="radio"
  formControlName="productMethod"
  id="radio{{i}}"
  name="productMethod"
  [value]=item>
<label class="custom-control-label"
  for="radio{{i}}">
  {{item.productName || '?'}}
</label>

Third, I wouldn't use an object as a form value because you cannot compare objects (easily) to be able to set a default. Use the productId and use a method to retrieve the corresponding product.

getProductById(id): any {
  return this.productList.find(p => p.productId == id);
}

Finally, I made other small changes to make your code a little better.

<div [formGroup]="productFormGroup">
  <div *ngFor="let item of productList; let i = index;">
    <input type="radio"
      formControlName="productMethod"
      id="radio{{i}}"
      name="productMethod"
      [value]=item.productId>
    <label class="custom-control-label"
      for="radio{{i}}">
      {{item.productName || '?'}}
    </label>
  </div>
</div>
{{ getProductById(productFormGroup.controls.productMethod.value) | json }}
Sign up to request clarification or add additional context in comments.

2 Comments

how to select "sprots" pre-selected on load page load or on some button events, any hints please?
this.productFormGroup.controls["productMethod"].patchValue({ productId: "105", productName: "sprots" }); <= this is not working if want to pre-selected value
3

A little bit late but let me leave this here. angular material has mat-radio-group, in your module, import {MatRadiomodule} from '@angular/material' also, import it inside @NgModule.

In your component.

this.formGroupVariable = this.fb.group({
    productItem: ['', Validators.required],
    . . .
});

Then in your template component,

<mat-radio-group *ngFor="let productItem of productList">
    <label for="{{productItem.value}}" class="radio-inline">
        <input id="{{productItem.value}}" 
               [value]="productItem.value"
               formControlName="productItem"                                          
               type="radio"
               name="requestType"
               [checked]="productItem.value==='Sports'">
               {{productItem.value}}
    </label>
</mat-radio-group>

I hope this helps.

2 Comments

appreciate your reply - but we do not like to use angular material
@var, you can replace the mat-radio-group element with a div element, you actually still get the same results.
0

1.-You need write "formArrayName"

2.-formControlName is enclosed by []

3.-radio buttons??? If you want radio buttons it's only a formControlName, not an array

<div [formGroup]="productFormGroup">
    <!---you need write "formArrayName"--->
    <div formArrayName="productMethods">
        <div *ngFor="let item of productList; let i = index">
            <div>
                <!--formControlName is enclosed by []-->
                <input type="checkbox" name="{{'acceptable'+i}}" [formControlName]="i">
                <label class="custom-control-label" 
                    for="{{ 'acceptable' + i}}">{{item.productName}}
               </label>
           </div>
        </div>
    </div>
</div>

this.myForm.controls['productMethods'].valueChanges.subscribe(value => {
      //value becomes, e.g. [true,false,false]
      values.forEach((v,index)=>{
         if (v)
           console.log(productList[i]);
      })
    }

NOTE: If you want radio buttons

<div [formGroup]="productFormGroup">
    <div *ngFor="let item of productList; let i = index" >
        <input type="radio" name="product" formControlName="product" [value]="item" >
    <label class="custom-control-label" 
        for="{{ 'acceptable' + i}}">{{item.productName}}</label>
    {{item.productname}}
  </div>
</div>

But your form is like

this.productFormGroup = this.formBuilder.group({
      product:''
    });

1 Comment

yes, i need radio buttons ( not checkbox), i will try to update stackblitz.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.