I am working off of an existing NgRx/Redux app and new to it (1st app). I have used a previous answer on SO and having trouble adding it to NgRx effects.
I have the following HTML/Angular in my component:
<div class="block">
<label id="lbl">File </label>
<input #fileInput type='file' (change)="_onChange($event)"/>
<button class="btn btn-sm" (click)="_uploadFile()">Upload The JSON File</button>
</div>
The TS file for the component has:
@Output() uploadFile = new EventEmitter();
_uploadFile() {
this.uploadFile.emit();
}
The module TS file:
uploadFile() {
this.store.dispatch(new PageActions.UploadFile());
}
The action file:
export class UploadFile implements Action {
readonly type = PageActionTypes.UploadFile;
constructor(public payload: File) { }
}
The effects file:
@Effect()
uploadFile$: Observable<Action> = this.actions$.pipe(
ofType(PACtions.PageActionTypes.UploadFile),
map( action => action.payload ),
// ...
);
From a previous SO answer I see this:
export class AppComponent {
uploadedData: any;
onChange(event) {
const reader = new FileReader();
reader.onload = e => {
const raw = (<FileReader>e.target).result as string;
const res = JSON.parse(raw);
this.uploadedData = res;
}
reader.readAsText(event.target.files[0]);
}
uploadFile() {
console.log(this.uploadedData);
// this.store.dispatch(new PageActions.UploadFile(this.uploadedData));
}
}
How do I get the onChange($event) and uploadedData to fit into my components, effects, and actions files? My component only has @Output ... stuff and the work happens in the effects file.
Update
I have a downloadStateFile like so.
In the component.ts file:
@Output() downloadStateFile = new EventEmitter();
_downloadStateFile() {
this.downloadStateFile.emit();
}
This works fine and is passed to the effects file to do the work:
@Effect({ dispatch: false })
downloadStateFile$ = this.actions$.pipe(
ofType(TheActionTypes.DownloadState),
withLatestFrom(this.store.select(fromSpace.getTheState)),
tap(([empty, wspace]) => {
console.log(JSON.stringify(wspace));
// This code below was suggested from the following link:
// https://stackoverflow.com/questions/42360665/angular2-to-export-download-json-file
var jsonState = JSON.stringify(wspace);
const clickElement = document.createElement('a');
clickElement.setAttribute('href', "data:text/json;charset=UTF-8," + encodeURIComponent(jsonState));
clickElement.setAttribute('download', "state-file.json");
clickElement.style.display = 'none';
document.body.appendChild(clickElement);
clickElement.click(); // simulate click
document.body.removeChild(clickElement);
})
);
I need the uploadState to do something similar but to take the state in the file and upload the state to the reducer. But first it needs to do all the FileReader in the effect as per the project.
Update #2
I only have one component as the FileUploader component created in your mock doesn't exist in mine so I only have:
<div class="block">
<label id="lbl">File </label>
<input #fileInput type='file' (change)="_onChange($event)"/>
<button class="btn btn-sm" (click)="_uploadFile()">Upload The JSON File</button>
</div>
I have this in that .ts file of the html above based on what you provided:
@Output() onChange = new EventEmitter();
_onChange(event) {
this.onChange.emit(event.target.files[0]);
}
In your code there is a second layer that is in readFile that passes in the inputFile payload. How do I add that to my above update? Thanks for your help.