I am making a simple code to accept a few values in one Form and display the list of form values on the right side. I have created Modal Class of the Form Fields and on Submit, I am sending data to Service. In the other component i have subscribed to the data. For some unknown Reason, My functions in this second component are getting called Twice. Also I am accepting an image file or Image URL in form and generating a preview of the file selected in form and also in list. To Generate the preview of this file in Form, it works flawlessly but in Second component, the same code goes into infinite loop. Any
my main Form Component html
<div class="row form">
<div class="col-8">
<form [formGroup]="songMetadata" (submit)="onSubmit(songMetadata)">
<div class="row">
<div class="col form-data">
<mat-form-field>
<mat-label>Song Name</mat-label>
<input matInput formControlName="songName" />
</mat-form-field>
<br />
<br />
<mat-form-field>
<mat-label>Artist Name</mat-label>
<input matInput formControlName="artistName" />
</mat-form-field>
<br />
<br />
<mat-form-field>
<mat-label>Album Name</mat-label>
<input matInput formControlName="albumName" />
</mat-form-field>
<br />
<br />
<mat-form-field>
<mat-label>Spotify URL</mat-label>
<input matInput formControlName="url" />
</mat-form-field>
<br />
<br />
<mat-form-field>
<mat-label>Other Description</mat-label>
<textarea
matInput
formControlName="description"
rows="4"
></textarea>
</mat-form-field>
<br />
<br />
<button
type="submit"
class="btn btn-primary"
[disabled]="
songMetadata.invalid ||
(!isImageFileSelected && !isImageURLEntered)
"
>
Submit
</button>
</div>
<div class="col image-upload">
<div
dropZone
class="text-center dropzone"
(hovered)="changeIsHover($event)"
(dropped)="fileDropped($event)"
[class.hovering]="isHovering"
>
<img
*ngIf="isImageFileSelected || isImageURLEntered"
[src]="imagePreview"
alt=""
width="192"
height="190"
/>
<div
class="drop-text"
*ngIf="!isImageFileSelected && !isImageURLEntered"
>
Drag And Drop File Here
</div>
</div>
<input
type="text"
placeHolder="Or Enter URL"
(blur)="loadPreviewFromURL($event)"
/>
<br />
<label for="files" class="btn btn-primary">Or Select Image</label>
<br />
<input
id="files"
style="visibility:hidden;"
type="file"
(change)="fileSelected($event)"
/>
<br />
<!-- <input type="file" /> -->
</div>
</div>
</form>
</div>
<!-- List View -->
<div class="col-4">
<list></list>
</div>
</div>
Main Component TS.
import { DataService } from "./data.service";
import { AngularFireStorageModule } from "@angular/fire/storage";
import { Component, OnInit } from "@angular/core";
import { FormGroup, FormBuilder, Validators } from "@angular/forms";
import { Observable } from "rxjs";
import { ISong } from "./song";
import { Data } from "@angular/router";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"]
})
export class AppComponent implements OnInit {
songMetadata: FormGroup;
selectedFile: File = null;
isImageFileSelected: boolean;
isImageURLEntered: boolean;
isHovering: boolean;
song: ISong;
imagePreview: any;
// // Upload Related Stuff
// task: AngularFireUploadTask;
// snapshot: Observable<any>;
constructor(
private formBuilder: FormBuilder,
private service: DataService // private storage: AngularFireStorage
) {
this.isImageFileSelected = false;
this.isHovering = false;
this.isImageURLEntered = false;
}
ngOnInit() {
this.songMetadata = this.formBuilder.group({
songName: ["xzcvzxv", Validators.required],
artistName: ["xzcvcxzv", Validators.required],
albumName: ["zxcvcxv", Validators.required],
url: ["zxcvvc", Validators.required],
description: ["zxcvzcxv", Validators.required]
});
}
fileSelected(event: any) {
this.isImageFileSelected = true;
this.isImageURLEntered = false;
this.selectedFile = event.target.files[0];
this.loadPreview();
}
fileDropped(event: FileList) {
this.isImageFileSelected = true;
this.isImageURLEntered = false;
this.selectedFile = event.item(0);
this.loadPreview();
}
onSubmit(songForm: FormGroup) {
event.preventDefault();
if (this.isImageFileSelected) {
this.song = {
name: songForm.value.songName,
artist: songForm.value.artistName,
album: songForm.value.albumName,
url: songForm.value.url,
description: songForm.value.description,
imageFile: this.selectedFile,
imageURL: null
};
} else {
this.song = {
name: songForm.value.songName,
artist: songForm.value.artistName,
album: songForm.value.albumName,
url: songForm.value.url,
description: songForm.value.description,
imageFile: null,
imageURL: this.imagePreview
};
}
this.service.addSong(this.song);
}
changeIsHover(isHovering: boolean) {
this.isHovering = isHovering;
}
loadPreview = () => {
let reader = new FileReader();
reader.readAsDataURL(this.selectedFile);
reader.onload = event => {
this.imagePreview = reader.result;
};
console.log("PREVIEW HIT");
};
loadPreviewFromURL(event: any) {
console.log(event.target.value);
this.isImageURLEntered = true;
this.isImageFileSelected = false;
this.imagePreview = event.target.value;
}
}
list component HTML
<div *ngFor="let s of songs; let i = index">
<div class="col-4">
<img
*ngIf="s?.imageURL"
[src]="livePrvw(s?.imageURL)"
width="100"
height="100"
alt="Image URL Preview"
/>
<img
*ngIf="s?.imageFile"
[src]="livePreview(s?.imageFile)"
width="100"
height="100"
alt="Image FILE Preview"
/>
</div>
<div class="col-8">
{{ s.name }}
</div>
</div>
listComponent TS
import { DataService } from "./../data.service";
import { ISong } from "./../song";
import { Component, OnInit, OnChanges } from "@angular/core";
@Component({
selector: "list",
templateUrl: "./list.component.html",
styleUrls: ["./list.component.scss"]
})
export class ListComponent implements OnInit {
songs: ISong[];
// song: ISong;
constructor(private service: DataService) {}
ngOnInit() {
this.service.songsAsObservable.subscribe(data => {
this.songs = data;
});
}
// also getting called twice
livePreview(file: File) {
// Going into infinite loop
// let newReader = new FileReader();
// let imagePreview: any;
// newReader.readAsDataURL(file);
// newReader.onload = event => {
// imagePreview = newReader.result;
// };
console.log(file);
}
// getting called twice somehow
livePrvw(imageURL: string) {
console.log(imageURL);
return imageURL;
}
}
To Reiterate the methods in ListComponent Get Called Twice for no reason and FileReader Code working in Main Component does no work in ListComponent (Goes into infinite Loop)
Any Help Is Much Appreciated