Reputation: 2124
I am getting the following error in my meanjs app -
Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope <- uiJqDirective
http://errors.angularjs.org/1.4.7/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope%20%3C-%20uiJqDirective
at REGEX_STRING_REGEXP (angular.js:68)
at angular.js:4289
at Object.getService [as get] (angular.js:4437)
at angular.js:4294
at getService (angular.js:4437)
at Object.invoke (angular.js:4469)
at angular.js:7080
at forEach (angular.js:336)
at Object.<anonymous> (angular.js:7078)
at Object.invoke (angular.js:4478)
I have a ui-jq directive which is as follows -
'use strict';
/**
* 0.1.1
* General-purpose jQuery wrapper. Simply pass the plugin name as the expression.
*
* It is possible to specify a default set of parameters for each jQuery plugin.
* Under the jq key, namespace each plugin by that which will be passed to ui-jq.
* Unfortunately, at this time you can only pre-define the first parameter.
* @example { jq : { datepicker : { showOn:'click' } } }
*
* @param ui-jq {string} The $elm.[pluginName]() to call.
* @param [ui-options] {mixed} Expression to be evaluated and passed as options to the function
* Multiple parameters can be separated by commas
* @param [ui-refresh] {expression} Watch expression and refire plugin on changes
*
* @example <input ui-jq="datepicker" ui-options="{showOn:'click'},secondParameter,thirdParameter" ui-refresh="iChange">
*/
angular.module('ui.jq', ['ui.load']).
value('uiJqConfig', {}).
directive('uiJq', ['$scope', 'uiJqConfig', 'JQ_CONFIG', 'uiLoad', '$timeout', function uiJqInjectingFunction($scope, uiJqConfig, JQ_CONFIG, uiLoad, $timeout) {
return {
restrict: 'A',
compile: function uiJqCompilingFunction(tElm, tAttrs) {
if (!angular.isFunction(tElm[tAttrs.uiJq]) && !JQ_CONFIG[tAttrs.uiJq]) {
throw new Error('ui-jq: The "' + tAttrs.uiJq + '" function does not exist');
}
var options = uiJqConfig && uiJqConfig[tAttrs.uiJq];
return function uiJqLinkingFunction($scope, elm, attrs) {
function getOptions(){
var linkOptions = [];
// If ui-options are passed, merge (or override) them onto global defaults and pass to the jQuery method
if (attrs.uiOptions) {
linkOptions = $scope.$eval('[' + attrs.uiOptions + ']');
if (angular.isObject(options) && angular.isObject(linkOptions[0])) {
linkOptions[0] = angular.extend({}, options, linkOptions[0]);
}
} else if (options) {
linkOptions = [options];
}
return linkOptions;
}
// If change compatibility is enabled, the form input's "change" event will trigger an "input" event
if (attrs.ngModel && elm.is('select,input,textarea')) {
elm.bind('change', function() {
elm.trigger('input');
});
}
// Call jQuery method and pass relevant options
function callPlugin() {
$timeout(function() {
elm[attrs.uiJq].apply(elm, getOptions());
}, 0, false);
}
function refresh(){
// If ui-refresh is used, re-fire the the method upon every change
if (attrs.uiRefresh) {
$scope.$watch(attrs.uiRefresh, function() {
callPlugin();
});
}
}
if ( JQ_CONFIG[attrs.uiJq] ) {
uiLoad.load(JQ_CONFIG[attrs.uiJq]).then(function() {
callPlugin();
refresh();
}).catch(function() {
});
} else {
callPlugin();
refresh();
}
};
}
};
}]);
I have tried to load $scope with the directive, but I think I have done it wrongly. Can anyone suggest what am I doing wrong or where else should i look to find the correct problem
Upvotes: 1
Views: 2176
Reputation: 30098
You don't have to inject scope in your directive, simply remove $scope
in the array.
directive('uiJq', [
'$scope', // YOU HAVE TO REMOVE THIS!
'uiJqConfig',
'JQ_CONFIG',
'uiLoad',
'$timeout',
function uiJqInjectingFunction(
$scope, // REMOVE THIS AS WELL
uiJqConfig,
JQ_CONFIG,
uiLoad,
$timeout) {
/* ... */
}])
You already have the scope of the directive inside the linking function returned by your compile function
return function uiJqLinkingFunction($scope, elm, attrs) {
/* ... */
};
So your directive should only have these injected:
directive('uiJq', [
'uiJqConfig',
'JQ_CONFIG',
'uiLoad',
'$timeout',
function (
uiJqConfig,
JQ_CONFIG,
uiLoad,
$timeout) {
/* ... */
}])
Upvotes: 1
Reputation: 6089
Do not inject $scope. Instead, replace compile by link, which has the scope as its first parameter:
link: uiJqLinkingFunction(scope, tElm, tAttrs) {
Upvotes: 1