ng2-file-upload custom filter with observable

29 views
Skip to first unread message

Amar bl

unread,
Feb 9, 2018, 6:36:50 AM2/9/18
to Angular and AngularJS discussion
HI,

I'm using ng2-file-upload with angular 5. I'm trying to write a custom filter where I want to compare file headers (parsed from a CSV file) with table headers (coming from server response)

here's my code -

fileTemplateFilter() {
    return Observable.create(observable => {
        this.uploader.options.filters.push({
            name: 'fileTemplateFilter',
            fn: (item, options) => {
                var type = item.type || null;
                if (type == "application/pdf") return true;
                this.fileUploadLoader = true;
                let tableHeaders, fileHeaders;
                Observable.forkJoin([
                    this.getCsvHeaders(item.name, 1).subscribe((res: any) => {
                        tableHeaders = res;
                        console.log(tableHeaders);
                    }),
                    this.getFileHeaders(item.rawFile).subscribe(res => {
                        fileHeaders = res;
                        console.log(fileHeaders);
                    })
                ]).subscribe(() => {
                    if (fileHeaders && tableHeaders) {
                        var is_same = (fileHeaders.length == tableHeaders.length) && fileHeaders.every(function (element, index) {
                            return element === tableHeaders[index];
                        });
                        if (is_same == true) {
                            this.fileUploadLoader = false;
                            observable.next(is_same);
                            return observable.complete();
                        } else {
                            console.error('file template doesn\'t match for this file - ' + item.name + ' ...!', 'Error');
                            this.fileUploadLoader = false;
                            observable.next(is_same);
                            return observable.complete();
                        }
                    } else {
                        this.fileUploadLoader = false;
                        observable.next(false);
                        return observable.complete();
                    }
                })
            }
        })
    })
}
I was using this filter in AngularJS & now I want the similar in Angular 5. Finally, I want to only return true/false from this filter. but I'm stuck at Observables.

I'm calling this function fileTemplateFilter() in constructor. But it doesn't work when I select a file to upload. And it's returning this error - ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable ... at ForkJoinSubscriber.

Thank you

Sander Elias

unread,
Feb 13, 2018, 1:38:53 AM2/13/18
to Angular and AngularJS discussion
Hi Amar,

I assume your function needs to return an observable of type boolean?
Based on this assumption, this should do the trick:

function fileTemplateFilter() {
return Observable.create(observable => {
this.uploader.options.filters.push({
name: "fileTemplateFilter",
fn: (item, options) => {
var type = item.type || null;
if (type == "application/pdf") return of(true);
this.fileUploadLoader = true;
return Observable.forkJoin([
this.getCsvHeaders(item.name, 1),
this.getFileHeaders(item.rawFile)
]).pipe(
map(
([fileHeaders, tableHeaders]) =>
fileHeaders.length == tableHeaders.length &&
fileHeaders.every(function(element, index) {
return element === tableHeaders[index];
})
),
tap(isSame => {
// this is a side effect, and should not be here actually!
this.fileUploadLoader = !isSame;
})
);
}
});
});
}

There are still some issues left in there, mostly around error handling. You might want to add something that logs the state to the console. You can use tap for that.
Reply all
Reply to author
Forward
0 new messages