Reputation: 1431
I have research through the internet with this popular error and I have found no solution to my problem.
What I have is a jQuery iframe post message function that receive strings from a different domain. When it get the string it will need to store it to Angular and save to the database. What I am having the trouble is, trying to update angular so that recognizes the changes.
So here is my code:
.controller('jobOrderController', function(Jobs, socketio) {
var vm = this;
var myImage;
$.receiveMessage(
function(e) {
myImage = e.data;
vm.$apply(function() {
vm.orderData.guideImage = e.data
});
},
'http://aaa.com'
);
vm.createOrders = function() {
vm.message = '';
Jobs.createOrders(vm.orderData)
.success(function(data) {
vm.orderData = '';
vm.message = data.message;
});
};
})
$.receiveMessage
will listen for incoming string data and then when it receive it should just save it to my "controller, vm". I know that my message is being received as I can alert them.
I know that I am going it wrong but everything I read is using $scope.apply
so I thought it would work the same way using "this". But it doesn't seem to be updated to angular.
Upvotes: 2
Views: 5551
Reputation: 25807
You can just do this:
.controller('jobOrderController', function($scope, Jobs, socketio) {
var vm = this;
$.receiveMessage(
function(e) {
myImage = e.data;
$scope.$apply(function() {
vm.orderData.guideImage = e.data
});
},
'http://aaa.com'
);
});
The this
works differently inside the Angular's controller. It's not always same as the $scope
and $scope
is the object which contains $apply
method.
Upvotes: 0
Reputation: 10548
The controllerAs
syntax is just (currently) sugar for $scope.foo
(if your controllerAs
is set to foo
). As a result, this
will actually point at $scope.foo
in this instance and not $scope
, which is why you will be unable to invoke any of $scope
's actions through this
. To use any of those, you will have to explicitly use $scope
.
The above answers all answer with a solution on how to fix the short-term problem, that is, you using $scope.$apply
in the controller.
Honestly, the issue here isn't that you can't use $scope.$apply
- I'm not sure exactly what you are trying to do but one of the main rules of Angular is that you have to do everything through Angular; $.receiveMessage
is decidedly not Angular. Wrap your $.receiveMessage
into a service; that service should also handle the $scope.$apply
. This will help reduce code duplication and make your controller agnostic to the implementation of the service.
There may already be a library that exists that does this that avoids using the heavy requirement of jQuery.
Upvotes: 0
Reputation: 3733
For $apply
, you can not use this
. $scope
and this
are different instance so this
can not access $apply
.
Check snippet:
angular.module('myApp', []).controller('MyCtrl', function($scope) {
var vm = this;
setTimeout(function() {
$scope.$apply(function() {
vm.text = 'Submit';
});
}, 0);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl as ctrl">
<button>{{ctrl.text}}</button>
</div>
Upvotes: 0
Reputation: 2223
I see that you are using john papa's guideline to avoid the use of $scope
.
You just forgot to declare vm (standing for viewmodel) at the beginning of your controller:
var vm = this;
EDIT: the guideline also says :
"Consider using $scope in a controller only when needed. For example when publishing and subscribing events using $emit, $broadcast, or $on."
For $apply
as well, you need to explicitly use $scope.$apply
Upvotes: 1