PWA approach to uploading files


#1

Do we have any options for browsing for files to upload - in a browser - without using a form?
Can we use Transfer?
If in a form, how does Transfer, which expects a string, handle the file passed from the input?
error: cordova.js:381 Wrong type for parameter “filePath” of FileTransfer.upload: Expected String, but got File.


Ionic Desktop App - Picture Upload
Upload image from browser - PWA?
Upload files from browser when Ionic app is deployed as a web app
Ionic - Profile Image Upload (Mobile / Deskptop)
Ng2-file-upload - Can't bind to 'uploader' since it isn't a known property
Ionic native File Transfer in Browser
#2

You could check out ng2-file-upload on Github. I’ve played around with the demo, but haven’t coded with it seriously.

More generally: this appears to be a hard problem. I asked a related question to someone who knows a LOT more Angular than I do, and his response was, “I have no idea how to do that.” Specifically re: Ionic, there’s been an open Github issue for months about styling the file input button. The standard CSS tricks for that don’t work, because mobile doesn’t behave the same way as desktop. And there are browser security issues about giving an app access to the user’s file system, so a lot of attempts to get away from the file button aren’t going to work.

As with many other things, PWA functionality appears to be lagging behind Cordova plugins. If you come up with something nice, please post, because I’m interested But at this moment, I either have to decide to do a lot of work on something “small”, or accept that my PWA file picker is not going to look as good as my mobile file picker.


#3

Hi Aaron, thanks for responding.

I was working on ng2-file-upload yesterday after after posting. I almost have it working but am dealing with some CORS issues on my server end. I have not yet reached the point of worrying about what the button looks like as I am still trying to make it just work.
Can I ask, do you have it working and if so, with what backend? I am working with Node and am able to use the Ionic Native Transfer successfully but not yet with ng2-file-upload.
Client side seems to be working - if not pretty.


#4

At the moment I’m using the standard <input type="file"> with error trapping, nothing that makes use of Angular or Ionic. I decided to prioritize other things, because it sounds as though Ionic might focus more on PWA UI soon, so I figured I’d wait and see what happened on that front, before trying myself. I’m using Firebase (both database and storage) as a backend.

Something I forgot to mention in the last post: Angular 2 doesn’t bind to <input type="file"> the way it binds to other input values. Perhaps intentionally? Not sure. An added complication I figured I’d point out if you haven’t run into it yet.


#5

Ya, I had no luck going that route so am trying hard to get the ng-file-upload to work.
Also, just noticed there is an ng-file-uploader as well that I will give a whirl.

If someone on the inside has any input on this with PWA UI - I’d sure like to hear about it.


#6

Ok, I just got the ng-file-upload to work with my node backend.

Full UI so far, looks like:

It is going to a Node backend, using authentication and passing variables.


PWA - Cordova-camera-plugin
#7

Here is a brief description of what is working for me. Feel free to improve:
( I have skipped the authorization requirements )

In my Component:

import { FileSelectDirective, FileDropDirective, FileUploader } from '../../../node_modules/ng2-file-upload';
const URL = 'https://locationofyourserverandapiendpoint';

export class Page1 {
uploader:FileUploader;
  hasBaseDropZoneOver:boolean;
  hasAnotherDropZoneOver:boolean;

  public fileOverBase(e:any):void {
    this.hasBaseDropZoneOver = e;
  }

  public fileOverAnother(e:any):void {
    this.hasAnotherDropZoneOver = e;
  }

_//NOTE: because I am using authorization I am passing the token through the file uploader - otherwise not required_

constructor(platform: Platform, public navCtrl: NavController, auth: AuthService) {
this.uploader = new FileUploader({authToken:'Bearer '+stored_token ,url: URL+"/VARTOBEPASSEDWITHFILE"});
}

Here is the template html: (as it pertains to the state of the image in previous post - needs work):

<ion-grid>
        <ion-row>
            <ion-col width-40 [ngStyle]="{'background-color': 'Bisque'}">
                <h3>Select files</h3>
                <div ng2FileDrop [ngClass]="{'nv-file-over': hasBaseDropZoneOver}" (fileOver)="fileOverBase($event)" [uploader]="uploader" class="well my-drop-zone">
                    Drop Files Here
                </div>
                <br/> Multiple
                <input type="file" [ngStyle]="{'background-color': 'Bisque'}" ng2FileSelect [uploader]="uploader" multiple /><br/>
            </ion-col>
            <ion-col width-60>
                <h3>Upload queue</h3>
                <p>Queue length: {{ uploader?.queue?.length }}</p>
                <table class="table">
                    <tbody>
                        <tr *ngFor="let item of uploader.queue">
                            <td><strong>{{ item?.file?.name }}</strong></td>
                            <td *ngIf="uploader.isHTML5" nowrap>{{ item?.file?.size/1024/1024 | number:'.2' }} MB</td>
                            <td *ngIf="uploader.isHTML5">
                                <progress id="progressbar" max="100" value="{{ item.progress }}"> </progress>
                                <div id="progressbarlabel">{{ item.progress }} %</div>
                            </td>
                            <td class="text-center">
                                <span *ngIf="item.isCancel"><ion-icon name="close-circle"></ion-icon></span>
                                <span *ngIf="item.isError"><ion-icon name="trash"></ion-icon></span>
                            </td>
                            <td nowrap>
                                <button ion-button icon-right *ngIf="!item.isSuccess" (click)="item.upload()" [disabled]="item.isReady || item.isUploading || item.isSuccess">Upload<ion-icon name="cloud-upload"></ion-icon></button>
                                <button ion-button icon-right *ngIf="!item.isSuccess" (click)="item.remove()" [ngStyle]="{'background-color': '#D2691E'}">Cancel<ion-icon name="close-circle"></ion-icon></button>
                                <button ion-button icon-right *ngIf="!item.isSuccess" color="danger">Remove<ion-icon name="trash"></ion-icon></button>
                                <button ion-button icon-right *ngIf="item.isSuccess" [ngStyle]="{'background-color': 'Green'}">Image Uploaded!<ion-icon name="checkmark-circle-outline"></ion-icon></button>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <div>
                    <div>
                        Queue progress:
                        <progress id="progressbar" [ngStyle]="{'background-color': 'Green'}" max="100" value="{{ uploader.progress }}"> </progress>
                        <div id="progressbarlabel">{{ uploader.progress }} %</div>
                    </div>
                    <button ion-button icon-right (click)="uploader.uploadAll()" [disabled]="!uploader.getNotUploadedItems().length">Upload all<ion-icon name="cloud-upload"></ion-icon></button>
                    <button ion-button icon-right (click)="uploader.cancelAll()" [ngStyle]="{'background-color': '#D2691E'}" [disabled]="!uploader.isUploading">Cancel all<ion-icon name="close-circle"></ion-icon></button>
                    <button ion-button icon-right color="danger" (click)="uploader.clearQueue()" [disabled]="!uploader.queue.length">Remove all<ion-icon name="trash"></ion-icon></button>
                    <button type="button" class="btn btn-warning btn-s" (click)="uploader.cancelAll()" [disabled]="!uploader.isUploading"></button>
                    <button type="button" class="btn btn-danger btn-s" (click)="uploader.clearQueue()" [disabled]="!uploader.queue.length">
                </button>
                </div>
            </ion-col>
        </ion-row>
    </ion-grid>

And finally the SCSS:

.my-drop-zone {
        border: dotted 3px blue;
        height: 100px;
        width: 100%;
    }
    .nv-file-over {
        border: dotted 3px red;
    }
    /* Default class applied to drop zones on over */
    .another-file-over-class {
        border: dotted 3px green;
    }
    html,
    body {
        height: 100%;
    }

Ng2-file-upload - Can't bind to 'uploader' since it isn't a known property
Upload array of photos to multer service
#8

Helo Please Does ng-file-upload for angular js work with ionic framework


#9

I am using ng2-file-upload


#10

Ok. Thanks and i guess it works perfectly with ionic? and does it work with ionic1?


#11

Not sure about perfectly but I am using it successfully.
I cannot say about Ionic1.