Jorrick Sleijster
Jorrick Sleijster

Reputation: 1156

ReferenceError: Require not defined when trying to use jquery in angular2

I am unable to use jQuery with angular2. Where a friend of mine got it working (on mac) it is not on my windows machine.

The errors:

jquery-ui.js:1 Uncaught ReferenceError: require is not defined
angular2.dev.js:23935 EXCEPTION: TypeError: jQuery(...).find(...).sortable is not a function in [null]
angular2.dev.js:23925 EXCEPTION: TypeError: jQuery(...).find(...).sortable is not a function in [null]BrowserDomAdapter.logError @ angular2.dev.js:23925
angular2.dev.js:23925 ORIGINAL EXCEPTION: TypeError: jQuery(...).find(...).sortable is not a functionBrowserDomAdapter.logError @ angular2.dev.js:23925
angular2.dev.js:23925 ORIGINAL STACKTRACE:BrowserDomAdapter.logError @ angular2.dev.js:23925
angular2.dev.js:23925 TypeError: jQuery(...).find(...).sortable is not a function at EditPresentationComponent.ngOnInit 

The piece of code where we use jquery.

import { Component, OnInit, ElementRef, Inject } from 'angular2/core';

declare var jQuery: any;

    @Component({
        selector: 'edit-presentation',
        templateUrl: 'app/Edit Presentation/edit_presentation.component.html'
    })

export class EditPresentationComponent implements OnInit {
    elementRef: ElementRef;

    isMyPresentationEmpty = true;

    constructor(@Inject(ElementRef) elementRef: ElementRef) {
        this.elementRef = elementRef;
    }

    ngOnInit() {
        var self = this;

        // Initialize Sortable on lists
        var oldList, newList, item, oldIndex;
        jQuery(this.elementRef.nativeElement).find('.slide-categories .sortable-list').sortable({
            start: function(event, ui) {
                item = ui.item;
                oldIndex = item.index();
                newList = oldList = ui.item.parent().parent();
            },
            change: function(event, ui) {  
                if (ui.sender) newList = ui.placeholder.parent().parent();
                // Check for empty list and hide/show instruction text
                if (jQuery('.my-presentation-column .agile-list').has('li:not(".ui-sortable-helper")').length) {
                    self.isMyPresentationEmpty = false;
                } else {
                    self.isMyPresentationEmpty = true;
                }
            },
            stop: function(event, ui) {
                if (oldList[0] != jQuery(event.toElement).parent().parent().parent().parent()[0]) {
                    if (jQuery(event.target).parent().hasClass('slide-categories')) {
                        if (oldIndex == 0) {
                            jQuery(event.target).prepend(item.clone());
                        } else {
                            jQuery(event.target).find('li:eq(' + (oldIndex - 1) + ')').after(item.clone());
                        }
                    } else {
                        item.remove();
                    }
                }
            },
            connectWith: ".sortable-list"
        }).disableSelection();

Overal when I execute npm install jquery or npm install jquery-ui I get

`[email protected] extraneous

as result, so it is installed.

I hope someone can help me with this.

Upvotes: 1

Views: 3722

Answers (2)

Thierry Templier
Thierry Templier

Reputation: 202176

Here is the way I make it work:

  • Include corresponding JS files in the main HTML file

    <script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
    <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
    
  • Wrap jquery().storable into a custom directive

    @Directive({
      selector: '[sortable]'
    })
    export class SortableDirective {
      constructor(private elementRef:ElementRef) {
      }
    
      ngOnInit() {
        $(this.elementRef.nativeElement).sortable({
          start: function(event, ui) {
            console.log('start');
          },
          change: function(event, ui) {  
            console.log('change');
          },
          stop: function(event, ui) {
            console.log('stop');
          }
        }).disableSelection();
      }
    }
    
  • Use it this way

    @Component({
      selector: 'app',
      template: `
        <ul sortable>
          <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
          <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
        </ul>
    `,
      directives: [ SortableDirective ]
    })
    export class App implements AfterViewInit {
    }
    

See this plunkr: https://plnkr.co/edit/gQnKzqdHCY82LOCFM1ym?p=preview.

Regarding the require problem, you could load jquery-ui from SystemJS since it understand the require function. Here is a sample:

<script>
  System.config({
    map: {
      'jquery-ui': 'nodes_module/.../jquery-ui.js'
    }
  });
</script>

Then you can import it this way:

import jqueryui from 'jquery-ui';

Upvotes: 0

ArcSine
ArcSine

Reputation: 644

If you are using typescript and angular2, you should just install the typings for jquery and jquery-ui. You could then load jQuery as such:

import "jquery-ui"
import * as $ from "jquery"

The other issue you seem to be having is that jquery-ui is looking for require, which is not present in the browser natively. I would double check how you are loading jquery-ui as it might be introducing bugs as well

Upvotes: 1

Related Questions