9

I'm trying to format a diff inside an Angular directive using diff2html and var jq = $.noConflict();

I've created an Angular constant to hold jQuery and am passing it into the directive as so:

app.js

(function () { //IIFE to enable strict mode
    'use strict';

    angular.module('dashboard', ['ui.router', 'ngSanitize'])
        .config(['$interpolateProvider', function ($interpolateProvider) {
            $interpolateProvider.startSymbol('[[[').endSymbol(']]]');
        }])
        .constant('jQuery', window.jQuery);
})();

directive.js

(function () { //IIFE to enable strict mode

    'use strict';

    angular.module('dashboard')
        .directive("loadDiff", ['$http', 'jQuery', function($http, $) {
            return {
                restrict: "A",
                link: function(scope, elem, attrs) {

                    $http.get("diff url here").success(function (data) {
                        var diff2htmlUi = new Diff2HtmlUI({diff: data});
                        diff2htmlUi.draw('#line-by-line');
                    });
                }
            }
        }]);
})();

The Problem

When it runs, I get the following error:

TypeError: $ is not a function at Diff2HtmlUI._initSelection at new Diff2HtmlUI

Debugging this you can see that when Diff2HtmlUI is instantiated it tries to set the body and this likely fails due to the conflict with var jq = $.noConflict();.

  Diff2HtmlUI.prototype._initSelection = function() {
    var body = $('body');
    var that = this;

How can I fix this issue? I was hoping passing in jQuery as $ would override the noconflict conflict?

4
  • 1
    add jquery before angular, remove this constant cause it is useless. Defininf function($http, $) is funny but not doing anything... Commented May 5, 2017 at 16:44
  • @PetrAveryanov jQuery is already defined as the first include. That answer was suggested here: stackoverflow.com/questions/34402898/… Commented May 5, 2017 at 19:42
  • See this demo, I cannot reproduce the bug: plnkr.co/edit/hLnuvQ9kHRRdsaHYK3SS?p=preview Commented May 7, 2017 at 19:34
  • Question edited, issue is related to var jq = $.noConflict(); Commented May 8, 2017 at 8:54

1 Answer 1

1

I don't really get why you are passing jQuery down to your directive. Since you loaded it directly, you and diff2html already have access to it through the global window object.

Also, you probably just want to pass the directive element instead of an external div id, just pass it as $(elem) since it expects a jQuery object or DOM query string.

angular.module('dashboard', [])
  .config(['$interpolateProvider', function ($interpolateProvider) {
    $interpolateProvider.startSymbol('[[[').endSymbol(']]]');
  }])
  .constant('jQuery', window.jQuery)
  .directive('loadDiff', ['$http', function ($http) {
    return {
      restrict: 'A',
      link: function (scope, elem, attrs) {

        $http({
          url: 'https://api.github.com/repos/rtfpessoa/diff2html/pulls/106.diff',
          headers: {
            accept: 'application/vnd.github.v3.diff'
          }
        })
        .then(function (resp) {
          var diff2htmlUi = new Diff2HtmlUI({ diff: resp.data });
          diff2htmlUi.draw($(elem));
        })
          
      }
    }
  }]);
<html>

  <head>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/diff2html/2.3.0/diff2html.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/diff2html/2.3.0/diff2html.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/diff2html/2.3.0/diff2html-ui.js"></script>
    <script data-require="[email protected]" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
    <script data-require="[email protected]" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  </head>

  <body ng-app="dashboard">
    <div load-diff="load-diff">Loading diff...</div>
  </body>
  
</html>

Sign up to request clarification or add additional context in comments.

2 Comments

Question updated, related to var jq = $.noConflict(); and Angular running after this.
With $ still injected in the directive? can you try removing it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.