I have a property called files
in my child component, which is an input type=file
. With that property I can check if the user selected a file to upload so I can disable the submit button if there are no files inside the input.
My problem is that now I have the submit button in the parent component so I can't check the property files
to enable the button when there's a file inside the input.
So, how can I access the files property from the parent component and check if the input contains a file or not?
I already tried with @ViewChild
decorator with something like this this.childComponent.files
but I'm getting undefined. I also tried @Output
but I could not make it work.
EDIT: ADDED CODE
Parent Component TS:
import { Component, OnInit, ViewChild } from '@angular/core';
import { StepState } from '@covalent/core';
import { StepThreeComponent } from './step-three/step-three.component';
import { StepTwoComponent } from './step-two/step-two.component';
import { StepOneComponent } from './step-one/step-one.component';
@Component({
selector: 'app-user-verification',
templateUrl: './user-verification.component.html',
styleUrls: ['./user-verification.component.scss']
})
export class UserVerificationComponent implements OnInit {
@ViewChild(StepThreeComponent) stepThreeComponent: StepThreeComponent;
@ViewChild(StepTwoComponent) stepTwoComponent: StepTwoComponent;
@ViewChild(StepOneComponent) stepOneComponent: StepOneComponent;
checkFiles: any;
//EXECUTE ALL UPLOAD FUNCTIONS
uploadAllFiles() {
this.stepThreeComponent.uploadSingle();
this.stepOneComponent.uploadSingle();
this.stepTwoComponent.uploadSingle();
console.log('No FUnciona')
}
ngOnInit() {
this.checkFiles = this.stepOneComponent.files;
console.log(this.checkFiles)
}
}
Parent Component HTML:
<td-steps>
<td-step #step1 sublabel="Suba una copia de la parte delantera de su Cédula de Identidad" [active]="true" [disabled]="false" (activated)="activeStep1Event()" [state]="stateStep1" (deactivated)="deactiveStep1Event()">
<ng-template #head1 td-step-label><span>Foto de Cédula de Identidad (I)</span></ng-template>
<app-step-one></app-step-one>
</td-step>
<td-step #step2 [active]="true" label="Foto de Cédula de Identidad (II)" sublabel="Suba una copia de la parte trasera de su Cédula de Identidad" [state]="stateStep2" [disabled]="false" disableRipple>
<app-step-two></app-step-two>
</td-step>
<td-step #step3 label="Selfie con Cédula de Identidad" sublabel="Subir Selfie" [state]="stateStep3" [disabled]="true" [active]="true">
<app-step-three></app-step-three>
<ng-template td-step-actions>
<button [disabled]="!checkFiles" (click)="uploadAllFiles()">SUBIR TODO</button>
</ng-template>
</td-step>
</td-steps>
children component TS:
import { Component } from '@angular/core';
import { UploadService } from '../../../services/upload.service';
import * as firebase from 'firebase/app';
import "firebase/storage";
import { Upload } from '../../../services/upload';
import * as _ from "lodash";
@Component({
selector: 'app-step-one',
templateUrl: './step-one.component.html',
styleUrls: ['./step-one.component.scss']
})
export class StepOneComponent {
selectedFiles: FileList;
currentUpload: Upload;
files: any;
disabled: any;
constructor(private upSvc: UploadService) { }
//Upload Service
detectFiles(event) {
this.selectedFiles = event.target.files;
}
uploadSingle() {
let uid = firebase.auth().currentUser.uid;
let file = this.files
this.currentUpload = new Upload(file);
this.upSvc.pushUpload(this.currentUpload, uid)
}
}
children Component HTML:
<div>
<div layout="row">
<md-input-container tdFileDrop [disabled]="disabled" (fileDrop)="files = $event" (click)="fileInput.inputElement.click()" (keyup.enter)="fileInput.inputElement.click()" (keyup.delete)="fileInput.clear()" (keyup.backspace)="fileInput.clear()" flex>
<input mdInput placeholder="select or drop files" [value]="files?.length ? (files?.length + ' files') : files?.name" [disabled]="disabled" readonly/>
</md-input-container>
<button md-icon-button *ngIf="files" (click)="fileInput.clear()" (keyup.enter)="fileInput.clear()">
<md-icon>cancel</md-icon>
</button>
<td-file-input class="push-left-sm push-right-sm" #fileInput [(ngModel)]="files" multiple [disabled]="disabled">
<md-icon>folder</md-icon>
<span class="text-upper">Browse...</span>
</td-file-input>
</div>
<div *ngIf="currentUpload">
<div class="progress">
<div class="progress-bar progress-bar-animated" [ngStyle]="{ 'width': currentUpload?.progress + '%' }"></div>
</div>
Progress: {{currentUpload?.name}} | {{currentUpload?.progress}}% Complete
</div>
</div>
EDIT #2:
html parent:
<app-step-one #StepOneComponent></app-step-one>
ts parent:
ngAfterViewInit() {
this.checkFiles = this.stepOneComponent.getFiles();
}
getFiles() {
this.checkFiles = this.stepOneComponent.getFiles();
console.log(this.checkFiles);
}
ts child added:
getFiles() {
return this.files
}
I also tried this.stepOneComponent.files;
but it was not working either. After that I created getFiles()
in child component to see if I could get the file inside the input and it worked. I was able to do a console.log()
from the parent component and get the file data. But what I need to do is to check for changes automatically and not with a function inside a button.
Edit #3 (for duplicate): That question doesn't help me because I need to check for changes automatically and not manually.