I'm facing an issue with converting controllers to components preparing my application for Angular 2, but the problem the migration is not going well, I have the ui-router to route between states and using resolve in a few controllers, the version with controller is working but the version of components now working at all, I followed a lot of guides and seems I'm doing good for code but its not working for me.
I have the following module with controller:
(function () {
'use strict';
angular
.module('app.sample', [])
.config(config);
/** @ngInject */
$stateProvider
.state('app.sample', {
url : '/sample',
views : {
'content@app': {
templateUrl: 'app/main/sample/sample.html',
controller : 'SampleController as vm'
}
},
resolve: {
SampleData: function (myService) {
return myService.getSample(); // I return a promise here
}
}
});
}
})();
Controller:
(function ()
{
'use strict';
angular
.module('app.sample')
.controller('SampleController', SampleController);
/** @ngInject */
function SampleController(SampleData)
{
var vm = this;
vm.helloText = SampleData.data.helloText;
}
})();
The above code working well, BUT After making it as a component its become like this:
(function () {
'use strict';
angular
.module('app.sample', [])
.config(config);
/** @ngInject */
function config($stateProvider) {
// State
$stateProvider
.state('app.sample', {
url: '/sample',
views: {
'content@app': {
template: '<sample></sample>'
}
},
resolve: {
SampleData: function (myService) {
return myService.getSample(); // I return a promise here
}
}
});
}
})();
Component:
(function () {
'use strict';
angular
.module('app.sample')
.component('sample', {
templateUrl: 'app/main/sample/sample.html',
bindings: {
},
controller: Sample
});
/** @ngInject */
function Sample(SampleData) {
var $ctrl = this;
$ctrl.helloText = SampleData.data.helloText;
}
})();
But now its not working and gives me the following error:
Error: [$injector:unpr] Unknown provider: SampleDataProvider <- SampleData
http://errors.angularjs.org/1.5.7/$injector/unpr?p0=SampleDataProvider%20%3C-%20SampleData
at angular.js:68
at angular.js:4502
at Object.getService [as get] (angular.js:4655)
at angular.js:4507
at getService (angular.js:4655)
at injectionArgs (angular.js:4679)
at Object.invoke (angular.js:4701)
at $controllerInit (angular.js:10234)
at nodeLinkFn (angular.js:9147)
at angular.js:9553
My dependencies inside bower.json:
"dependencies": {
"angular": "1.5.7",
"angular-animate": "1.5.7",
"angular-aria": "1.5.7",
"angular-cookies": "1.5.7",
"angular-material": "1.1.0-rc.5",
"angular-messages": "1.5.7",
"angular-resource": "1.5.7",
"angular-sanitize": "1.5.7",
"angular-ui-router": "1.0.0-beta.1",
"jquery": "2.2.4",
"mobile-detect": "1.3.2",
"moment": "2.13.0"
}
Any idea what the problem, what I'm missing?
Finally solved it, I misunderstood that how the components are working.
First I change SampleData
to sampleData
, Pascal Case but with first letter small.
Then inside the module
i changed the template
to template: '<sample sample-data="$resolve.sampleData"></sample>'
and resolve
to :
resolve: {
sampleData: function (msApi) {
return msApi.resolve('sample@get');
}
}
And for component
I changed the binding as well:
bindings: {
sampleData: '='
},
And inside the controller
of component
I removed SampleData
from signature and called it like this $ctrl.helloText = $ctrl.sampleData.data.helloText;
.
So the final code now is like : For Module:
(function () {
'use strict';
angular
.module('app.sample', [])
.config(config);
/** @ngInject */
function config($stateProvider) {
// State
$stateProvider
.state('app.sample', {
url: '/sample',
views: {
'content@app': {
template: '<sample sample-data="$resolve.sampleData"></sample>'
}
},
resolve: {
sampleData: function (myService) {
return myService.getSample(); // I return a promise here
}
}
});
}
})();
And component like this:
(function () {
'use strict';
angular
.module('app.sample')
.component('sample', {
templateUrl: 'app/main/sample/sample.html',
bindings: {
sampleData: '='
},
controller: Sample
});
/** @ngInject */
function Sample() {
var $ctrl = this;
$ctrl.helloText = $ctrl.sampleData.data.helloText;
}
})();
And finally worked.
Edit: P.S.: Outside the question and answer scope, If you use component without state too, you need to get the data inside controller instead of resolve, so you can call components wherever you want.