How to Fix 'jQuery is Not Defined' Error with ng2-datetime in Angular 2

If you’re working with Angular 2 and using the ng2-datetime library to add a datetime picker to your application, you may encounter the frustrating error: "jQuery is not defined". This error occurs because ng2-datetime (a third-party datetime picker component) depends on jQuery and Moment.js to function, but these dependencies are not properly loaded or configured in your Angular 2 project.

In this blog, we’ll break down why this error happens and provide a step-by-step guide to resolve it. We’ll cover installing dependencies, configuring Angular CLI, adding type definitions, and troubleshooting common issues—ensuring your datetime picker works seamlessly.

Table of Contents#

  1. Understanding the "jQuery is Not Defined" Error
  2. Prerequisites
  3. Step-by-Step Solutions
  4. Troubleshooting Common Issues
  5. Verifying the Fix
  6. References

1. Understanding the "jQuery is Not Defined" Error#

The "jQuery is not defined" error occurs when the ng2-datetime library tries to access jQuery, but jQuery is not available in the global scope of your application. Here’s why this happens:

  • Dependency Chain: ng2-datetime relies on jQuery for DOM manipulation and Moment.js for date parsing/formatting. If jQuery isn’t loaded before ng2-datetime, the library cannot initialize.
  • Angular’s Module System: Angular 2 uses a modular architecture, and by default, third-party libraries like jQuery are not loaded globally unless explicitly configured.

2. Prerequisites#

Before proceeding, ensure you have the following set up:

  • An existing Angular 2 project (created with Angular CLI v1.x, as Angular 2 uses the older angular-cli.json config file).
  • Node.js (v6.x or later) and npm (v3.x or later) installed.
  • Basic familiarity with Angular CLI and TypeScript.

3. Step-by-Step Solutions#

Let’s resolve the error with these actionable steps:

Step 1: Install Required Dependencies#

First, install ng2-datetime, jQuery, and Moment.js via npm. These are the core dependencies:

npm install ng2-datetime jquery moment --save
  • ng2-datetime: The datetime picker component itself.
  • jquery: Required for DOM manipulation (used internally by ng2-datetime).
  • moment: Required for date parsing/formatting.

Step 2: Configure Angular CLI to Load jQuery Globally#

Angular 2 uses the Angular CLI (v1.x) with a configuration file named angular-cli.json (not angular.json—that’s for Angular 6+). To make jQuery and Moment.js available globally (so ng2-datetime can access them), add their script paths to the scripts array in angular-cli.json.

How to Edit angular-cli.json:#

  1. Open angular-cli.json in the root of your Angular 2 project.
  2. Locate the apps array (under config). Each app in this array has a scripts property where you can list global scripts.
  3. Add the paths to jQuery and Moment.js in the scripts array. Order matters: Load jQuery first, followed by Moment.js (since ng2-datetime depends on both).

Example angular-cli.json snippet:

{
  "project": {
    "version": "1.0.0",
    "name": "your-angular2-app"
  },
  "apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": ["assets", "favicon.ico"],
      "index": "index.html",
      "main": "main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      "styles": ["styles.css"],
      "scripts": [
        "../node_modules/jquery/dist/jquery.min.js",  // Load jQuery first
        "../node_modules/moment/moment.js",           // Then Moment.js
        "../node_modules/ng2-datetime/src/vendor/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"  // Optional: ng2-datetime’s internal vendor script
      ],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ]
}

Why This Works:#

Adding scripts to angular-cli.json ensures they are bundled and loaded into the global scope (window object) when your app starts. This makes $ (jQuery) and moment available for ng2-datetime to use.

Step 3: Add Type Definitions for jQuery (TypeScript)#

If you’re using TypeScript (the default for Angular 2), the compiler may throw errors like "Cannot find name '$'" because it doesn’t recognize jQuery types. To fix this, install jQuery type definitions:

npm install @types/jquery --save-dev

This installs @types/jquery, which provides TypeScript interfaces for jQuery, allowing the compiler to recognize $ and jQuery methods.

Optional: Verify Type Definitions#

If TypeScript still complains about jQuery, add jquery to the types array in tsconfig.json (under compilerOptions):

{
  "compilerOptions": {
    "types": ["jquery", "moment"]  // Add jQuery and Moment.js types
  }
}

Step 4: Import ng2-datetime in Your Angular Module#

Next, import Ng2DatetimeModule into the Angular module where you plan to use the datetime picker (e.g., AppModule).

Open src/app/app.module.ts and add the import:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { Ng2DatetimeModule } from 'ng2-datetime'; // Import ng2-datetime
import { AppComponent } from './app.component';
 
@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    Ng2DatetimeModule  // Add to imports array
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Step 5: Verify Component Implementation#

Now, use the ng2-datetime selector in your component template to render the datetime picker. For example, in src/app/app.component.html:

<!-- app.component.html -->
<h1>My Datetime Picker</h1>
<datetime-picker
  [(ngModel)]="selectedDate"
  dateFormat="yyyy-MM-dd"
  timeFormat="HH:mm"
></datetime-picker>

In src/app/app.component.ts, define the selectedDate property:

import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  selectedDate: Date; // Initialize the date property
}

4. Troubleshooting Common Issues#

If the error persists, check these common issues:

Issue 1: Incorrect Order of Scripts in angular-cli.json#

jQuery must be loaded before Moment.js and ng2-datetime scripts. If jQuery is loaded after, ng2-datetime will not find it.

Fix: Ensure the scripts array in angular-cli.json follows this order:

"scripts": [
  "../node_modules/jquery/dist/jquery.min.js",  // 1. jQuery first
  "../node_modules/moment/moment.js",           // 2. Then Moment.js
  "../node_modules/ng2-datetime/src/vendor/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"  // 3. Then ng2-datetime vendor scripts (if needed)
]

Issue 2: Version Conflicts#

ng2-datetime may require specific versions of jQuery or Moment.js. Check the peerDependencies in node_modules/ng2-datetime/package.json to ensure compatibility.

Example: If ng2-datetime requires jQuery ^2.2.0, avoid using jQuery 3.x (which may have breaking changes).

Issue 3: jQuery Not Loaded Globally#

Verify jQuery is loaded by checking the browser’s Network tab (in DevTools) for jquery.min.js. If it’s missing, ensure the path in angular-cli.json is correct (e.g., ../node_modules/jquery/dist/jquery.min.js).

You can also test jQuery availability in the browser console:

console.log(window.jQuery); // Should return the jQuery object if loaded
console.log($); // Should return the jQuery function

Issue 4: TypeScript Typing Errors#

If TypeScript throws Cannot find name '$', ensure @types/jquery is installed and added to tsconfig.json’s types array. As a last resort, add declare var $: any; at the top of your component file to bypass type checks (not recommended for production).

5. Verifying the Fix#

To confirm the error is resolved:

  1. Restart your Angular development server:
    ng serve
  2. Open your app in a browser (usually at http://localhost:4200).
  3. Check the browser console (F12) for errors. If no "jQuery is not defined" error appears, the fix worked!
  4. Test the datetime picker: Click it to ensure the calendar dropdown appears and you can select a date/time.

6. References#

By following these steps, you’ll resolve the "jQuery is not defined" error and get your ng2-datetime picker working in Angular 2. If you run into further issues, feel free to leave a comment below!