Ngx-bootstrap: Error when using modal - There is no directive with "exportAs" set to "bs-modal"

Created on 29 Jun 2016  路  15Comments  路  Source: valor-software/ngx-bootstrap

I am getting the following error in the console when loading a template HTML, I am using Angular 2 RC3:

There is no directive with "exportAs" set to "bs-modal"

I have imported ng2-bootstrap using the following:

<script src="lib/ng2-bootstrap/bundles/ng2-bootstrap.min.js"></script>

Here is my template:

<div bsModal #lgModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" (click)="lgModal.hide()" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title">title</h4>
            </div>
            <div class="modal-body">
                <my-cmp></my-cmp>
            </div>
        </div>
    </div>
</div>

Here is my component.ts

import {CORE_DIRECTIVES} from '@angular/common';
import {BS_VIEW_PROVIDERS, MODAL_DIRECTVES} from 'ng2-bootstrap/ng2-bootstrap';


@Component({
    selector: 'siso',
    templateUrl: 'app/component.html',
    styleUrls: ['app/component.css'],
    directives: [MODAL_DIRECTVES, CORE_DIRECTIVES],
    viewProviders: [BS_VIEW_PROVIDERS]
})

Here is system.config.js:

(function(global) {

    // map tells the System loader where to look for things
    var map = {
        'app':                        'dist/app', // 'dist',
        'rxjs':                       'dist/lib/rxjs',
        'angular2-in-memory-web-api': 'dist/lib/angular2-in-memory-web-api',
        '@angular':                   'dist/lib/@angular',
        'moment':                     'dist/lib/moment/moment.js',
        'ng2-bootstrap':              'dist/lib/ng2-bootstrap'
    };

    // packages tells the System loader how to load when no filename and/or no extension
    var packages = {
        'app':                        { main: 'main.js',  defaultExtension: 'js' },
        'rxjs':                       { defaultExtension: 'js' },
        'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
        'dist/lib/ng2-bootstrap':              { defaultExtension: 'js' }
    };

    var paths = {
        'ng2-bootstrap/ng2-bootstrap':   'dist/lib/ng2-bootstrap/ng2-bootstrap'
    };

    var ngPackageNames = [
        'common',
        'compiler',
        'core',
        'http',
        'platform-browser',
        'platform-browser-dynamic',
        'router',
        'router-deprecated',
        'upgrade'
    ];
    // Individual files (~300 requests):
    function packIndex(pkgName) {
        packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
    }
    // Bundled (~40 requests):
    function packUmd(pkgName) {
        packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
    }
    // Most environments should use UMD; some (Karma) need the individual index files
    var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;

    // Add package entries for angular packages
    ngPackageNames.forEach(setPackageConfig);

    // No umd for router yet
    packages['@angular/router'] = { main: 'index.js', defaultExtension: 'js' };

    var config = {
        map: map,
        packages: packages,
        paths: paths
    };

    System.config(config);

})(this);

Most helpful comment

how to fix this please Agular2 Rc.4 There is no directive with "exportAs" set to "bs-modal" exact instruction please :(

All 15 comments

RC.3 is currently not supported. There is already a PR: #631

After upgrading to 1.0.22 this is still not working, I have also upgraded to using angular/@forms

@geejay Are there other messages in the console? Is ng2-bootstrap even loaded?

No other messages are in the console. I checked and ng2-bootstrap.min.js is loaded.

It is working when I am not bundling, so there is a problem with the bundling process (i.e systemjs).

So basically RC4 and the modal component should work together?

@geejay Yes they should work together.

I found something:

'ng2-bootstrap/ng2-bootstrap': 'dist/lib/ng2-bootstrap/ng2-bootstrap'

Here you are pointing to the unbundled ng2-bootstrap, but you should point to the bundle:

'ng2-bootstrap/ng2-bootstrap': 'dist/lib/ng2-bootstrap/bundles/ng2-bootstrap'

Note: I don't know if you need to add the .min or even the .min.js at the end.

Merci Dinistro

I'll try it when I get the chance.

i'm facing the exact same problem (right after i updated from 1.0.17 to 1.0.23).
the provided solution (if worked) isn't very clear to me.
i'm not using a system.config.js file.
will appreciate any help

Dinistro's answer fixed this for me. Are you sure you are importing the bundle? Maybe it's the way your bundle is being created?

how to fix this please Agular2 Rc.4 There is no directive with "exportAs" set to "bs-modal" exact instruction please :(

Same here with RC4. Still get it although I do see the exportAs: 'bs-modal' line in modal.component.js. Not sure what's wrong.

i fixed it .. my main.ts is

and just add this disableDeprecatedForms(),provideForms()

import { bootstrap }    from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
import {Component, provide,enableProdMode} from "@angular/core";
import {LocationStrategy, HashLocationStrategy} from '@angular/common';
import { appRouterProviders } from './routes/app.routes';
import { disableDeprecatedForms, provideForms } from '@angular/forms';
import {HTTP_PROVIDERS,XHRBackend} from '@angular/http';


enableProdMode();
bootstrap(AppComponent, [HTTP_PROVIDERS,disableDeprecatedForms(),provideForms(),appRouterProviders,provide(LocationStrategy, {useClass: HashLocationStrategy})]);

then my app.component.ts is
and just add this
viewContainerRef:ViewContainerRef;
this.viewContainerRef = viewContainerRef;

import { Component ,ComponentResolver,ViewContainerRef} from '@angular/core';
import { ActivatedRoute,ROUTER_DIRECTIVES } from '@angular/router';
@Component({
  selector: 'sc-mgr',
  template: '<router-outlet></router-outlet>',
 directives: [ROUTER_DIRECTIVES]
})
export class AppComponent {
  viewContainerRef:ViewContainerRef;
  constructor(private compiler: ComponentResolver,viewContainerRef:ViewContainerRef){
    this.compiler.clearCache();
    this.viewContainerRef = viewContainerRef;
  }

}

and finally i can use it on my dashboard.ts
i remove my code and leave the important sample :)

import {Component, ViewChild,ViewContainerRef} from '@angular/core';
import {CORE_DIRECTIVES} from '@angular/common';
import {MODAL_DIRECTIVES, BS_VIEW_PROVIDERS,ModalDirective} from 'ng2-bootstrap/ng2-bootstrap';


@Component({
  selector: 'base_level',
  directives: [MODAL_DIRECTIVES, CORE_DIRECTIVES],
  viewProviders:[BS_VIEW_PROVIDERS],
  template: `

      <div class="modal modal-danger fade"  bsModal #childModal="bs-modal"  tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" [config]="{backdrop: 'static'}" aria-hidden="true">
        <div class="modal-dialog">
          <div class="modal-content">
            <div class="modal-header">
              <button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="hideChildModal()">
                <span aria-hidden="true">&times;</span></button>
              <h4 class="modal-title">@{{title}}</h4>
            </div>
            <div class="modal-body">
              <p>@{{hello}}&hellip;</p>
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-outline" (click)="hideChildModal()">Save changes</button>
            </div>
          </div>
        </div>
      </div>

  `
})

export class DashComponent {
  title:string = "hi";
  msg:string = "hello";
  @ViewChild('childModal') public childModal: ModalDirective;
  public constructor(viewContainerRef:ViewContainerRef) {


  }
  public showChildModal():void {
    this.childModal.show();
  }

  public hideChildModal():void {
    this.childModal.hide();
  }

}


i don't know if this necessary but here's my system config
i just add this on map
'ng2-bootstrap': 'node_modules/ng2-bootstrap',
and this as a package
'ng2-bootstrap': { main: 'ng2-bootstrap.js', defaultExtension: 'js' },

/**
* System configuration for Angular 2 samples
* Adjust as necessary for your application needs.
*/
(function(global) {
  // map tells the System loader where to look for things
  var map = {
    'app':                        'scr/angular2_app', // 'dist',
    '@angular':                   'node_modules/@angular',
    'ng2-bootstrap':              'node_modules/ng2-bootstrap',
    'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
    'rxjs':                       'node_modules/rxjs',
    'moment':                     'node_modules/moment/moment.js',
  };
  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app':                        { main: 'main.js',  defaultExtension: 'js' },
    'rxjs':                       { defaultExtension: 'js' },
    'ng2-bootstrap':              { main: 'ng2-bootstrap.js', defaultExtension: 'js' },
    'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
  };
  var ngPackageNames = [
    'common',
    'compiler',
    'core',
    'forms',
    'http',
    'platform-browser',
    'platform-browser-dynamic',
    'router',
    'router-deprecated',
    'upgrade',
  ];
  // Individual files (~300 requests):
  function packIndex(pkgName) {
    packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
  }
  // Bundled (~40 requests):
  function packUmd(pkgName) {
    packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
  }
  // Most environments should use UMD; some (Karma) need the individual index files
  var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
  // Add package entries for angular packages
  ngPackageNames.forEach(setPackageConfig);
  var config = {
    map: map,
    packages: packages
  };
  System.config(config);
})(this);

Fixed it too! In my case, it was silly that I forgot to include the modal directives in my app!

I couldn't fix this using SystemJS and Angular 2.4. I eventually moved the project to Webpack and not using SystemJS. Then this problem disappeared.

Best answer ever :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MrBlaise picture MrBlaise  路  3Comments

Scooviese picture Scooviese  路  3Comments

phmello picture phmello  路  3Comments

juanitavollmering picture juanitavollmering  路  3Comments

hugonne picture hugonne  路  3Comments