Don Chambers
Don Chambers

Reputation: 4251

How do I structure the import from a third-party angular2 app

I am not sure how to structure the import statement for a third-party library.

I am trying to use ng2-file-upload from an angular2 project in visual studio. https://github.com/valor-software/ng2-file-upload

I have this in my component:

import {FILE_UPLOAD_DIRECTIVES, FileUploader} from 'ng2-file-upload';

Using Visual Studio, this will build and intellisense finds the directives in the library. At runtime I get this error:

GET http://localhost:54675/ng2-file-upload 404 (Not Found)

Obviously, that is not the correct path.

Below ss my directory structure. The import is in documentUpload.component.ts.

> wwwroot
> -------app
> ----------shared
> -------------documentUpload
> ----------------documentUpload.component.ts
> -------node_modules
> ----------ng2-file-upload
> -------------ng2-file-upload.js
> -------------components
> ----------------file-upload
> -------------------file-uploader.js

My source for ng2-file-upload is in the project root and a gulp file moves just the js and css to my wwwroot/node_modules folder. I think at design time it's using the source in my root (so intellisense works and it builds) but at runtime it's trying to pull from wwwroot and something is missing or referenced wrong.

Update: Based on feedback I added this module to the system.config as shown below:

    System.config({
        packages: {
            app: {
                format: 'register',
                defaultExtension: 'js'
            }
        },
        map: {
            'ng2fileupload': 'node_modules/ng2-file-upload/ng2-file-upload.js'
        }
    });

  System.import('app/boot')
        .then(null, console.error.bind(console));
  System.import('ng2fileupload')
        .then(null, console.error.bind(console));

At this point, I get a 404 error when loading: http://localhost:54675/node_modules/ng2-file-upload/components/file-upload/file-select

That file-select component is in a sub-directory under ng2-file-upload. I added it as a map module but that just produced similar errors for other components that it uses.

Current Progress Here is my index.html file.

<!DOCTYPE html>
<html>

<head>
    <title>FMS</title>
    <base href="/" />
    <!-- 1. Load libraries -->
    <script src="/node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="/node_modules/systemjs/dist/system.src.js"></script>
    <script src="/node_modules/rxjs/bundles/Rx.js"></script>
    <script src="/node_modules/angular2/bundles/angular2.dev.js"></script>
    <script src="node_modules/angular2/bundles/router.dev.js"></script>
    <script src="node_modules/es6-shim/es6-shim.js"></script>

    <script src="/node_modules/jquery/dist/jquery.js"></script>
    <script src="/node_modules/bootstrap/dist/js/bootstrap.js"></script>
    <script src="/node_modules/angular2/bundles/http.js"></script>
    <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="/node_modules/spinkit/css/spinkit.css" />

    <link rel="stylesheet" href="/app/assets/site.css" />

    <!-- 2. Configure SystemJS -->
    <script>
      System.config({
        packages: {
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        },
        map:{
        'ng2-file-upload':'node_modules/ng2-file-upload/ng2-file-upload.js'
        }

      });
      System.import('app/boot')
            .then(null, console.error.bind(console));
    </script>

</head>

<!-- 3. Display the application -->
<body>
    <fmssupport-app></fmssupport-app>
</body>

</html>

Here is my component:

import {Component} from 'angular2/core';
import {FILE_UPLOAD_DIRECTIVES} from 'ng2-file-upload';

@Component({
    selector: 'document-upload',
    templateUrl: 'app/shared/documentUpload/documentUpload.component.html',
    directives: [FILE_UPLOAD_DIRECTIVES]
})

export class DocumentUploadComponent {

}

And these are the error I get:

GET http://localhost:54675/node_modules/ng2-file-upload/components/file-upload/file-select 404 Error: XHR error (404 Not Found) loading http://localhost:54675/node_modules/ng2-file-upload/components/file-upload/file-select(…) GET http://localhost:54675/node_modules/ng2-file-upload/components/file-upload/file-drop 404 GET http://localhost:54675/node_modules/ng2-file-upload/components/file-upload/file-uploader 404 (Not Found)

From this I can see that it is finding the ng2-file-upload component but it fails when that component tries to load components in a subfolder.

Upvotes: 0

Views: 1373

Answers (3)

user2038560
user2038560

Reputation: 137

Basically I am following @Morgan G 's answer, but I mess around it a little bit. Now I provide my code here, hope it is helpful to others.


  1. Install ng2-file-upload npm install ng2-file-upload --save
  2. Import in index.html
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.js"></script>
<script src="node_modules/ng2-toastr/bundles/ng2-toastr.min.js"></script>

<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>

<!-- 2. Configure SystemJS -->
<script>
  System.config({
    packages: {
      app: {
        format: 'register',
        defaultExtension: 'js'
    },
    'ng2-file-upload': { "defaultExtension": "js" }
    },
  map: {
       "ng2-file-upload": "/node_modules/ng2-file-upload"
     }
  });
  System.import('app/main')
        .then(null, console.error.bind(console));
</script>

3. Import directive:

@Component({
...
directives: [FILE_UPLOAD_DIRECTIVES] })

And import {FILE_UPLOAD_DIRECTIVES, FileUploader} from 'ng2-file-upload/ng2-file-upload'; 4. Then you should be able to add

<input type="file" ng2-file-select [uploader]="uploader" multiple  />

in your template

Upvotes: 0

Edmond B
Edmond B

Reputation: 1

Index.html.. Where "libs" is your .js folder under wwwroot

 System.config({
        packages: {
            appScripts: {
                defaultExtension: 'js'
            }
            , 'ng2-file-upload': { defaultExtension: 'js' }
                }, map: { 'ng2-file-upload': 'libs/ng2-file-upload/' }
            }

    );

and component... {Directpry/File}

import {FILE_UPLOAD_DIRECTIVES, FileUploader} from 'ng2-file-upload/ng2-file-upload';

Upvotes: 0

Morgan G
Morgan G

Reputation: 3109

Usually you do this through the System.config file in your index.html which calls your angular app.

Something like this:

System.config({
        defaultJSExtensions: true,
        packages: {
            "/angular2": {"defaultExtension": false}
        },
        map: {
            'ng2-file-upload': 'node_modules/ng2-file-upload'
        }
});

You'll notice the map: function, this is an easy way to configure additional packages within angular2.

Edit:

Your index.html file should look something like this:

<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system.js"></script>
<script src="node_modules/ng2-file-upload></script> //Note how I am grabbing it here.
<script>
     System.config({
        packages: {
          app: {
            format: 'register',
            defaultJSExtensions: true
          },
        },
        map: {
            "ng2-file-upload": "/node_modules/ng2-file-upload"//This is so we map it to the name ng2-file-upload for use in our application.
          }
      });
</script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.js"></script>
<script src="node_modules/angular2/bundles/http.min.js"></script>
<script src="node_modules/angular2/bundles/router.min.js"></script>
<script>
  System.import('app/boot')
        .then(null, console.error.bind(console));
</script>

After doing this you should be able to:

import {Ng2-file-uploader} from 'ng2-file-upload'

I am not sure what the export of ng2-file-upload would be, so you'd have to find the name, and if the folder to the file is 3 directories down you'll have to reference it like:

'ng2-file-upload/second_directory/third_directory/name_of_component'

That should get it up and running.

The docs on System.js are pretty good and easy to read here is a good way to see how to add plugins to it from their github. https://github.com/systemjs/systemjs/blob/master/docs/overview.md#plugin-loaders

Hope this helps! Sorry I didn't post this yesterday, big blizzard here and power went out all day!

Edit 2:

Ok so a few things, you are specifying a file and not a directory in your map function, which is ok if you only ever want to use that specific file for ng2-file-upload. But you still actually spelt the file wrong which is giving you some headaches, it should be ng2-file-uploader.js.

Also,

{FILE_UPLOAD_DIRECTIVES} from 'ng2-file-upload';

That import statement is invalid, there is no FILE_UPLOAD_DIRECTIVES in the ng2-file-upload. It only has a FileUploader Class. You can check yourself from their source https://github.com/valor-software/ng2-file-upload/blob/master/components/file-upload/file-uploader.ts .

You could use:

import {FileUploader} from 'ng2-file-upload'

or

import {FileUploader as FILE_UPLOAD_DIRECTIVES} from 'ng2-file-upload'

I think some of the problems you are running into though, is the fact that you are not specifying the directory and only specifying the file directly. Which is why you are running into the error:

http://localhost:54675/node_modules/ng2-file-upload/components/file-upload/file-select

Because you are not referencing pulling the file-select module from the directory, you are only ever getting your file-uploader. You can work around this but in your HTML file you are not referencing this script at all. You need to have a script tag:

<script src="node_modules/ng2-file-upload></script>

Like I had mentioned previously.

Upvotes: 0

Related Questions