Unable to pass data to a controller inside a component in AngularJS - angularjs

I have following component
componentsModule.component('detailComponent', {
templateUrl: 'detailTemplate.html',
scope: {},
bindings: {
textParam: '='
},
controller: ['$mdDialog', function($mdDialog) {
this.textParam // this is undefined always
}]
});
I am loading template in a dialog from other controller like this
$scope.textParam = tParam;
const parentEl = angular.element(document.body);
$mdDialog.show({
template: '<detail-component text-param="$scope.textParam"></detail-component>',
ariaLabel: 'detailComponentDialog',
parent: parentEl
}).then((savedDatails) => {});
If I use binding as # then I get $scope.textParam as a string inside my controller in this.textParam but if I set binding as < or = then I get undefined

Related

Angular js binding "<" give undefined inside controller

I have "invite-friends-code" component which get data through binding "<". The problem is, it is pass correctly and show in the view directly, but when i trying to munipulate with it inside "invite-friends-code" controller it gives me "undefined"
component
const inviteFriendsCodeComponent = {
bindings: {
leagueCode: '<'
},
templateUrl: '/js/common/invite-friends-code/invite-friends-code.html'+assetsVersion,
controller: 'InviteFriendsCodeController'
}
binding using inside other component view:
<invite-friends-code league-code="$ctrl.leagueData.code"></invite-friends-code>
controller:
ctrl.$onInit = () => {
console.log(ctrl.leagueCode) // gives me undefined here
}
Your bindings are not initialized yet!
You can use $onInit function.
app.component('yourComponent', {
bindings: {
leagueCode: '<'
},
controller: function() {
var ctrl = this;
this.$onInit = function() {
console.log(this.leagueCode)
});
}
}
Official doc

Angular components, controller not loading

I have the following angular:
angular.module("app.components", []);
angular.module("app", [
"app.components"
]);
angular.module("app.components")
.component('testWidget', {
templateUrl: '/Widgets/TestWidget/Templates/TestWidget.template.html',
bindings: {
something: "="
},
controller: function () {
var ctrl = this;
// ctrl has nothing on it
}
});
<div ng-app="app">
<test-widget something="Shoopy"></test-widget>
</div>
but the something is not part of the object (this) in the controller. what have i missed?
two-way binding (expects a parent scope property to watch for value changes):
bindings: {
something: "="
}
A parent controller would need to set the property:
$scope.Shoopy = "hello world"
For parameter bindings use the following:
string value binding:
bindings: {
something: "#"
}
you forgot controllerAs since you're using this instead of $scope
try this
angular.module("app.components")
.component('testWidget', {
templateUrl: '/Widgets/TestWidget/Templates/TestWidget.template.html',
bindings: {
something: "="
},
controllerAs: "ctrl",
controller: function () {
var ctrl = this;
// ctrl has nothing on it
}
});

Sending data from component to view with this

My problem is with 'this'
I don't know how to call data from controller with 'this' i try ' ng-init="meProfileCtrl.getView()" ' and assign data in a way {{ user.name }}
'use strict';
function meProfileCtrl(DataService) {
var self = this;
this.getView = function () {
DataService.allData().then(function (response) {
self.user = response.data.me_view;
console.log(user);
}, function(error) {
alert("error");
});
}
};
angular.module('app').component('meprofile',{
templateUrl :'templates/alldata.html',
controller: meProfileCtrl,
bindings: {
getView: '=',
user: '='
}
}
);
Use the value of controllerAs which is$ctrl by the default, so if you didn't specify it you can use: $ctrl.getView()
But you can define it in your component, for example:
angular.module('app').component('meprofile',{
templateUrl :'templates/alldata.html',
controller: meProfileCtrl,
controllerAs: myctrl,// <-- here
bindings: {
getView: '=',
user: '='
}
}
);
and use: myctrl.getView() in your view
Component docs: https://docs.angularjs.org/guide/component

How to use $watch in angularjs component

I am using jCarousel for image thumbnail slider. but previously I was using directive for the same but now I changed my code to component. but now I am not able to use that link function and watch reload in component. because I am using first time component in agularjs.
//Previous code
directive('jblogcarousel', function() {
return {
restrict: 'A',
replace: true,
transclude: true,
scope: {
jitems: "="
},
templateUrl: '/templates/blog-carousel.html',
link: function link(scope, element, attrs) {
var container = $(element);
var carousel = container.find('.jcarousel');
carousel.jcarousel({
wrap: 'circular'
});
scope.$watch(attrs.jitems, function (value) {
carousel.jcarousel('reload');
});
container.find('.jcarousel-control-prev')
.jcarouselControl({
target: '-=1'
});
container.find('.jcarousel-control-next')
.jcarouselControl({
target: '+=1'
});
}
};
});
//Current code
.component('jCarousel', {
bindings: {
jitems: '='
},
templateUrl: '/templates/carousel.html'
})
From what I understood, in Angular 1.5 components bindings will bind the value to the controller.
So you can add a controller (with a $watch inside):
// bindings: { ... },
// templateUrl: '...',
controller: function ($scope) {
var vm = this;
console.log(vm.jitems); // vm.jitems should exist and be bound the value you passed to the component from the outside
// you should be able to watch this value like this
$scope.$watch(
function () { return vm.jitems; },
function (newValue) { console.log(newValue); }
);
}
Also, with components, you should in most situations use one way binding '<' instead of two-way binding '=', and use functions/events (binding '&') for the other direction.

Pass object to component

I have created a component that needs to have a reference to the object for which the component was created. I didn't make to work and all my trials have failed. Below, I try to describe the intention.
The component definition would maybe look like this:
angular
.module('myModule')
.component('myComponent', {
templateUrl: "template.html",
controller: [
MyController
],
bindings: {
myObject: '='
}
});
function MyController(myObject) {
var vm = this;
vm.myObject = myObject;
}
In a service I would like to create my object like this:
function createMyObject(args) {
var myObject = {some: data};
myObject.ref = "<my-component myObject='{{myObject}}'></my-component>";
return myObject;
}
Question
How can I pass data to angular component tag? Do I have to switch back to a component directive to make it work?
Any ideas are greatly appreciated. Thank you.
Solution 1
In your template:
<my-component key='$ctrl.myObject'></my-component>
In code:
angular
.module('myModule')
.component('myComponent', {
templateUrl: "template.html",
controller: [
'objectService'
MyController
],
bindings: {
key: '=' // or key: '<' it depends on what binding you need
}
});
function MyController(myObject, objectService) {
var vm = this;
vm.myObject.whatever(); // myObject is assigned to 'this' automatically
}
Solution 2 - via Component Bindings
Component:
angular
.module('myModule')
.component('myComponent', {
templateUrl: "template.html",
controller: [
'objectService'
MyController
],
bindings: {
key: '#'
}
});
function MyController(myObject, objectService) {
var vm = this;
vm.myObject = objectService.find(vm.key);
}
Usage:
function createMyObject(args) {
var myObject = {key: ..., some: data};
myObject.ref = "<my-component key='" + myObject.key + "'></my-component>";
return myObject;
}

Resources