2

I have an Angular 4 project where I upload files to firebase storage. I have based the uploader code on angular-firestarter. If I run this code it works fine.

I have included the upload.service.ts in my code and it worked fine, but after being away from it for a little time the upload.service.ts will no longer compile. I get an error: Argument of type '() => void' is not assignable to parameter of type 'Unsubscribe'. Type 'void' is not assignable to type 'undefined'. on the function that looks like this:

pushUpload(upload: Upload, desktopKey: string) {
    const storageRef = firebase.storage().ref();
    const uploadTask = storageRef.child(`${this.basePath}/${upload.file.name}`).put(upload.file);

    uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
        (snapshot: any) => {
            // upload in progress
            upload.progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        },
        (error) => {
            // upload failed
            console.log(error);
        },
        () => {
             // upload success
             upload.url = uploadTask.snapshot.downloadURL;
             upload.name = upload.file.name;
             this.saveDocumentData(upload, desktopKey);
        }
    );
}

It seems to be that the definition for this on function is wrong in my project (if I comment it it out the app works fine). Any idea on what can be causing such a problem and how to fix it?

If I compare the firebase.d.ts files for the two projects they are a bit different although both projects have "firebase": "^4.1.3" in package.json

from angular-firestarter

interface UploadTask {
    cancel ( ) : boolean ;
    catch (onRejected : (a : Error ) => any ) : firebase.Promise < any > ;
    on (event : firebase.storage.TaskEvent , nextOrObserver ? : null | Object , error ? : ( (a : Error ) => any ) | null , complete ? : ( ( ) => any ) | null ) : Function ;
    pause ( ) : boolean ;
    resume ( ) : boolean ;
    snapshot : firebase.storage.UploadTaskSnapshot ;
    then (onFulfilled ? : ( (a : firebase.storage.UploadTaskSnapshot ) => any ) | null , onRejected ? : ( (a : Error ) => any ) | null ) : firebase.Promise < any > ;
  }

from my project:

  interface UploadTask {
    cancel ( ) : boolean ;
    catch (onRejected : (a : Error ) => any ) : firebase.Promise < any > ;
    on (event : firebase.storage.TaskEvent , nextOrObserver ? : firebase.Observer < any , any > | null | ( (a : Object ) => any ) , error ? : ( (a : Error ) => any ) | null , complete ? : ( firebase.Unsubscribe ) | null ) : Function ;
    pause ( ) : boolean ;
    resume ( ) : boolean ;
    snapshot : firebase.storage.UploadTaskSnapshot ;
    then (onFulfilled ? : ( (a : firebase.storage.UploadTaskSnapshot ) => any ) | null , onRejected ? : ( (a : Error ) => any ) | null ) : firebase.Promise < any > ;
  }

I have deleted node_modules and package-lock.json and run npm install, but it didn't help.

I also tried restoring my project from a backup including node_modules and then it works, but when I delete node_modules and package-lock.json and npm install I get the error.

So any idea why I get a wrong typedefinition file in my project even though I install the same version of firebase?

my package.json file;

{
  "name": "docavea",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve --o",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "populate-db": "./node_modules/.bin/ts-node ./populate-db.ts",
    "populate-db2": "./node_modules/.bin/ts-node ./populate-db2.ts"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.3.2",
    "@angular/common": "^4.3.2",
    "@angular/compiler": "^4.3.2",
    "@angular/core": "^4.3.2",
    "@angular/flex-layout": "^2.0.0-beta.8",
    "@angular/forms": "^4.3.2",
    "@angular/http": "^4.3.2",
    "@angular/platform-browser": "^4.3.2",
    "@angular/platform-browser-dynamic": "^4.3.2",
    "@angular/platform-server": "^4.3.2",
    "@angular/router": "^4.3.2",
    "angularfire2": "^4.0.0-rc.1",
    "core-js": "^2.4.1",
    "firebase": "^4.1.3",
    "global": "^4.3.2",
    "lodash": "^4.17.4",
    "ng2-pdf-viewer": "^1.1.0",
    "ngx-bootstrap": "^1.7.1",
    "rxjs": "^5.4.2",
    "zone.js": "^0.8.12"
  },
  "devDependencies": {
    "@angular/cli": "^1.2.6",
    "@angular/compiler-cli": "^4.3.2",
    "@types/jasmine": "2.5.38",
    "@types/node": "~6.0.60",
    "@types/lodash": "^4.14.67",
    "codelyzer": "~2.0.0",
    "jasmine-core": "~2.5.2",
    "jasmine-spec-reporter": "~3.2.0",
    "karma": "~1.4.1",
    "karma-chrome-launcher": "~2.0.0",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^0.2.0",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.0",
    "ts-node": "^3.1.0",
    "tslint": "~4.5.0",
    "typescript": "^2.4.2"
  }
}
Jørgen Rasmussen
  • 1,143
  • 14
  • 31
  • without looking too closely, you at least loose the scope of `this` with `function()`, instead use fat arrow syntax `() =>` More: https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback – AT82 Jul 29 '17 at 08:57
  • 1
    ^4.1.3 means any version that does not change the major (4), latest available is 4.2.0 and that will get installed when you run npm install. If you scope to that exact version, meaning removing ^ it should work fine. Probably they changed the function definition in one of the newer releases. – Adrian Fâciu Jul 29 '17 at 09:51

1 Answers1

4

The problem comes from the handler of the completed method:

() => {
         // upload success
         upload.url = uploadTask.snapshot.downloadURL;
         upload.name = upload.file.name;
         this.saveDocumentData(upload, desktopKey);
      }

The inferred return type of this function is actually void, which worked just fine with the older version of firebase because the expected type was ( ) => any but in the new version this was changed to firebase.Unsubscribe which is defined as:

  type Unsubscribe = ( ) => undefined ;

Hence the error that void is not assignable to undefined.

You can fix this in several ways, for example you can return undefined from the arrow function.

Adrian Fâciu
  • 12,414
  • 3
  • 53
  • 68