For some weird reason, there are just no tutorials or code samples online showing how to use Angular2 Reactive forms with anything more than simple input or select dropdowns.
I need to create a form to let users select their avatar. (Image file)
The following doesn't work. (i.e. The Avatar property never shows any value changes.)
profile.component.html:
<form [formGroup]="profileForm" novalidate> <div class="row"> <div class="col-md-4 "> <img src="{{imgUrl}}uploads/avatars/{{getUserAvatar}}" style="width:150px; height:150px;float:left;border-radius:50%;margin-right:25px;margin-left:10px;"> <div class="form-group"> <label>Update Profile Image</label> <input class="form-control" type="file" formControlName="avatar"> </div> </div> <div class="col-md-8 "> <div class="form-group"> <label >Firstname: <input class="form-control" formControlName="firstname"> </label> </div> <div class="form-group"> <label >Lastname: <input class="form-control" formControlName="lastname"> </label> </div> <div class="form-group"> <label >Email: <input class="form-control" formControlName="email"> </label> </div> <div class="form-group"> <label >Password: <input class="form-control" type="password" formControlName="password"> </label> </div> </div> </div> </form> <p>Form value: {{ profileForm.value | json }}</p> <p>Form status: {{ profileForm.status | json }}</p>
profile.component.ts:
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import {Config} from '../../services/config.service'; import {AuthService} from '../../services/auth.service'; import {User} from '../../models/user.model'; @Component({ selector: 'app-profile', templateUrl: './profile.component.html', styleUrls: ['./profile.component.css'] }) export class ProfileComponent implements OnInit { authUser:User; profileForm : FormGroup; constructor(private authService:AuthService, private fb: FormBuilder) {} createForm() { this.profileForm = this.fb.group({ firstname: [this.authUser.firstname, Validators.required ], lastname: [this.authUser.lastname, Validators.required ], email: [this.authUser.email, Validators.required ], avatar: [this.authUser.avatar, Validators.required ], password:['xxxxxx', Validators.minLength(4)] }); } ngOnInit() { this.authUser = this.authService.getAuthUser(); this.createForm(); }
You can use [(ngModel)] with Reactive forms. This will a completely different directive than the one that would be used without the formControlName .
To work with Reactive forms, we must import the ReactiveFormsModule . We usually import it in root module or in a shared module. The ReactiveFormsModule contains all the form directives and constructs for working with angular reactive forms.
To use Reactive forms in your application you need to import ReactiveFormsModule in your parent module.
Simple answer can be found here. https://devblog.dymel.pl/2016/09/02/upload-file-image-angular2-aspnetcore/
The HTML
<input #fileInput type="file"/> <button (click)="addFile()">Add</button>
Component.ts
@ViewChild("fileInput") fileInput; addFile(): void { let fi = this.fileInput.nativeElement; if (fi.files && fi.files[0]) { let fileToUpload = fi.files[0]; this.uploadService .upload(fileToUpload) .subscribe(res => { console.log(res); }); } }
The service.ts
upload(fileToUpload: any) { let input = new FormData(); input.append("file", fileToUpload); return this.http.post("/api/uploadFile", input); }
I'm a bit late to this, but for anyone else that may come here looking for the same solution - This is my file input accessor that can be used with Reactive or Template-driven forms. Demo here.
There's some optional validation provided with it that can be used to check image dimensions and file size, extension, type, which is disabled by default.
npm i file-input-accessor
and add the module to your AppModule imports:
import {BrowserModule} from '@angular/platform-browser'; import {FileInputAccessorModule} from "file-input-accessor"; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, FileInputAccessorModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule {}
Then use your file input like any other input:
<!--Reactive Forms--> <input type="file" multiple [formControl]="someFileControl" /> <input type="file" multiple formControlName="someFileControl" /> <!--Template-driven--> <input type="file" name="file-input" multiple [(ngModel)]="fileList" />
You can subscribe to valueChanges property just like any other reactive control.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With