Antimo
Antimo

Reputation: 480

How to correctly use Bootstrap component in Typescript with JQuery

I'm just studying some TypeScript so I try to create a litte example with one simple modal windows that should appear when user click on a button. The example is really similar to: https://www.w3schools.com/bootstrap/tryit.asp?filename=trybs_ref_js_modal_js&stacked=h

The html page contains (just an extract of full code) a simple Bootstrap modal

  <!-- Modal -->
  <div class="modal fade" id="myModal" role="dialog">
    <div class="modal-dialog">

      <!-- Modal content-->
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">&times;</button>
          <h4 class="modal-title">Modal Header</h4>
        </div>
        <div class="modal-body">
          <p>Some text in the modal.</p>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>
      </div>

    </div>
  </div>

</div>

Then I try to simply attach a click event and using jquery try to show the modal (type script file):

import * as $ from "jquery";

$(document).ready(function(){
    console.log("Document ready!!");
    $("#myBtn").click(function(){
        ($("#myModal")).modal({backdrop: true});
    });
});

I have an error:

[ts] Property 'modal' does not exist on type 'JQuery'.

Apparently, the error is resolved using <any>$("#myModal") (but we loose type)

$(document).ready(function(){
    console.log("Document ready!!");
    $("#myBtn").click(function(){
        (<any>$("#myModal")).modal({backdrop: true});
    });
});

But running and click on button nothing happen, debugging the page I have an error:

Exception has occurred: TypeError

TypeError: r(...).modal is not a function at HTMLButtonElement. (/home/antimo/Desktop/programmazione/typescript/ts-vscode-boilerplate/dist/myapp.min.js:1:87688) at HTMLButtonElement.dispatch (/home/antimo/Desktop/programmazione/typescript/ts-vscode-boilerplate/dist/myapp.min.js:1:50053)

These are the dependencies with npm:

 "devDependencies": {
    "@types/bootstrap": "^3.3.36",
    "@types/chai": "^4.0.4",
    "@types/jquery": "^3.2.12",
    "@types/mocha": "^2.2.32",
    "browser-sync": "^2.17.3",
    "browserify": "^14.0.0",
    "chai": "^4.1.2",
    "gulp": "^3.9.1",
    "gulp-istanbul": "^1.1.1",
    "gulp-mocha": "^4.0.1",
    "gulp-sourcemaps": "^2.1.1",
    "gulp-tslint": "^8.0.0",
    "gulp-typescript": "^3.1.4",
    "gulp-uglify": "^3.0.0",
    "run-sequence": "^2.1.0",
    "tslint": "5.7.0",
    "typescript": "^2.0.3",
    "vinyl-buffer": "^1.0.0",
    "vinyl-source-stream": "^1.1.0",
    "wallabify": "0.0.15"
  },
  "dependencies": {
    "@types/bootstrap": "^3.3.36",
    "@types/jquery": "^3.2.12",
    "bootstrap": "^3.3.7",
    "jquery": "^3.1.1",
    "tsify": "^3.0.1"
  }

I have no experience so I know this has to be some simple error but can't find the problem now.

EDIT: Adding types "jquery" and "bootstrap" in tsconfig.json resolved the compile error, so now I can use:

 ($("#myModal")).modal({backdrop: true});

File tsconfig.json

    {
    "compilerOptions": {
        "target": "es5",
        "lib": ["es6", "dom"],
        "types": ["mocha", "jquery",  "bootstrap"],
        "sourceMap": true,
        "module": "commonjs",
        "moduleResolution": "node",
......
}

But error persist on line:

($("#myModal")).modal({backdrop: true});

Exception has occurred: TypeError

TypeError: r(...).modal is not a function
    at HTMLButtonElement.<anonymous>

Upvotes: 1

Views: 4563

Answers (2)

Amid
Amid

Reputation: 22382

When supplying typescript definitions you are merely instruct typescript compiler about what kind of functionality is present in the 3rd party package. They do not contain any implementation and do not affect your compiled sources in any way.

Therefore if you want to use bootstrap/jquery you must either manually include them in your HTML, or (and this is preferable way if we are speaking of modern javascript/typescript) - instruct your module loader/bundler how to find it and simply do:

import * as $ from "jquery";
import "bootstrap";

in your module. there are plenty of example how to set up your SystemJS, RequireJS or Webpack in order for them to serve bootstrap/jquery at runtime.

Upvotes: 7

wrager
wrager

Reputation: 872

It seems that you simply did not include index.d.ts from @types/bootstrap and/or @types/jquery node modules into your TypeScript compilation.

Upvotes: 1

Related Questions