Skip to content
This repository has been archived by the owner on Nov 20, 2018. It is now read-only.

Typescript Browser ReferenceError: qq is not defined #1838

Closed
2 of 6 tasks
fullykubed opened this issue May 18, 2017 · 4 comments
Closed
2 of 6 tasks

Typescript Browser ReferenceError: qq is not defined #1838

fullykubed opened this issue May 18, 2017 · 4 comments

Comments

@fullykubed
Copy link
Contributor

fullykubed commented May 18, 2017

Type of issue

  • Bug report
  • Feature request
  • Support request

Uploader type

  • Traditional
  • S3
  • Azure
Bug Report

Fine Uploader version

5.14.2

Browsers where the bug is reproducible

Chrome 58

Operating systems where the bug is reproducible

Ubuntu 17.04

Exact steps required to reproduce the issue

Note: This occurs in a Typescript Angular project being bundled by Webpack with the awesome-typescript-loader.

My tsconfig.json:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2015",
    "sourceMap": true,
    "outDir": "build",
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "noImplicitAny": false,
    "suppressImplicitAnyIndexErrors": true,
    "lib": ["es2015", "dom"],
    "allowJs": false
  },
  "exclude": [
    "node_modules",
    "app",
    "public"
  ],
  "awesomeTypescripteLoaderOptions": {

  }
}

Error was discovered using the below file snippet, but can also be reproduced using the first 26 lines of `fine-uploader.tests.ts'.

The error occurs at new qq.FineUploader(...).

All relevant Fine Uploader-related code that you have written

/// <reference types="fine-uploader" />
...
export class AboutComponent implements OnInit{


    editorDOM: HTMLElement;
    editorOutputDOM: HTMLElement;
    titleInput: HTMLElement;
    dateInput: HTMLElement;
    uploaderInput: HTMLElement;

    editor: ace.Editor;
    taggle: Taggle;
    uploader: FineUploader.qq;

    post: Post;

   ...
    getDOM(): void {
        this.editorDOM = document.getElementById("md-editor");
        this.editorOutputDOM = document.getElementById("md-editor-output");
        this.titleInput = document.getElementById("post-title");
        this.dateInput = document.getElementById("post-date");
        this.uploaderInput = document.getElementById("fine-uploader");
    }
   ...

    initUploader(): void {

        this.uploader = new qq.FineUploader({
            element: this.uploaderInput,
            validation: {
                allowedExtensions: ['png', 'jpeg', 'jpg', 'svg']
            },
            blobs: {
              defaultName: 'blog-image'
            },
            request: {
                endpoint: '/api/blog/post/image'
            },
            deleteFile: {
                enabled: true,
                endpoint: '/api/blog/post/image',
                forceConfirm: true
            },
            callbacks: {
              onComplete: (id, name, response) => {
                  if(response.success){
                      this.post.addImage(this.uploader.getUuid(id), name);
                      this.addInsertPictureListener(this.uploader.getUuid(id), name);
                  }
              },

              onDeleteComplete : (id, xhr, isError) => {
                 this.post.removeImage(this.uploader.getUuid(id));
              }

            }
        });

        //adds existing post pictures
        for(let image in this.post.images){
            let name = this.post.images[image];
            this.uploader.addInitialFiles([{
                name: name,
                uuid: image
            }]);
            this.addInsertPictureListener(image, name);
        }
    }
...

Detailed explanation of the problem

When trying to integrate fine-uploader with a Typescript project by following the example set in fine-uploader.tests.ts the project compiles correctly but the browser produces a reference error: ReferenceError: qq is not defined.

What is weird is that typescript will compile the project properly and the error only appears in runtime.

Now if I add a node.js require like let qq = require('fine-uploader') before using qq everything will work out fine. Though this seems a little too hacky to be the go-to solution.

@fullykubed
Copy link
Contributor Author

fullykubed commented May 19, 2017

So upon further digging into the codebase, it looks like fine-uploader uses UMD module design. Since Typescript users will in all likelihood use some sort of module mechanism other than the global namespace, this creates a problem with the way that the declaration file is currently structured.

It looks like the current declaration file is structured using this global declaration template. However, since the project can be modularized and Typescript users will almost definitely be using modules, it should use this template.

Why does it need to be this way? Because Typescript users won't have the qq variable exposed in the underlying javascript. So declare var qq at the end of the declaration file (which doesn't actually change the underlying code) will trick the Typescript compiler into thinking that qq exists (even though it doesn't) and then we will run into tricky runtime errors in the browser (my last several hours can attest ;) ). Since the typescript compiler doesn't complain, this is also probably why the code passed any build tests you had prior to deploying.

I would be happy to refactor the Typescript as best I can if you want. I have already altered it appropriately for my usecase, but I can expand my fixes to the entire scope and submit a pull request.

@singhjusraj
Copy link
Member

@jclangst Yes the current declaration file is structured using global declaration template and it is required that the fine-uploader JS file be included in project's index.html.
I see that you are using webpack for your angular 2 project, I've been using SystemJS and Rollup to generate bundles for my projects.
Rollup was one of the reasons I didn't modularized the TS def file, because it leads to problems in the prod bundle.

I see your point and I already wanted to look at this for a while now.
I'll take a look at your PR soon, thanks for your contribution.

@azampagl
Copy link

@jclangst What was your work-around to get the current version working for your use case? I'm running into the same issues due to qq not being exposed in the underlying JS.

@singhjusraj
Copy link
Member

Fixed in #1840 and released in version 5.15.0

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants