after a long time I have to concentrate an angular again.
But I fail...
... ng-repeat="n in DataController.getObjects"
myApp.controller('DataController', [function () {
console.log('test 1');
var getObjects = function () {
console.log('test 2');
return [1,2,3,4,5,6,7];
};
}]);
It is writing test 1 to console but not test 2. And the frontend does not get the array.
Any hint for me?
Regards
n00n
You have to expose method/variable which you want to access on page on this(context) of your controller. So that you can access that method/variable via controller alias as you you seems to be using controllerAs pattern.
Code
myApp.controller('DataController', [function () {
var self = this;
console.log('test 1');
var getObjects = function () {
console.log('test 2');
return [1,2,3,4,5,6,7];
};
self.getObjects = getObjects;
}]);
I hope you have already defined controller alias while using ng-controller directive, If you haven't used it, follow below.
ng-controller="DataController as dataCtrl"
ng-repeat="n in dataCtrl.getObjects()"
And as you can see you should call method in ng-repeat like getObjects() to get a array from method.
Related
For an old angular app (version 1), I was asked to upload some data via it. I used Selenium to execute a javascript script that replaces the Angular app's $scope upload function to something I can work with.
ie
angular.element(document.querySelector('#somecontroller')).scope().uploadFunc() { ... }
Unfortunately, the new function does not have access to the $scope and various local non $scope functions found within that library.
ie.
...uploadFunc() {
localNonScopeFunc // ERROR: localNonScopeFunc not defined
$scope // ERROR: $scope not defined
}
I was able to get access to $scope indirectly but I still can't access any local functions.
I'm pretty sure I just need to bind the controller's this to function to resolve both issues but not sure how...
How would I bind the replaced $scope function to the angular app?
Update 1:
// existing library
var someApp= angular.module('wApp', ['oc.lazyLoad', 'lookup','menu','prompt','service']);
someApp.controller('somecontroller', function ($scope, $timeout, $interval, $http, $ocLazyLoad, $rootScope, service)
{
$scope.uploadFunc = function() {
$scope.doSomething();
NonScopeLibraryFunc();
...bad blocking code
};
}
function NonScopeLibraryFunc() {
...
}
I have to change the uploadFunc code since its blocking functionality. So I try
// selenium JavaScriptExecutor
angular.element(document.querySelector('#somecontroller')).scope().uploadFunc = function () {
$scope.doSomething(); // Error: $scope not defined
NonScopeLibraryFunc() // Error: NonScopeLibraryFunc not defined
...better non-blocking code
};
Neither $scope or NonScopeLibraryFunc() can be used. I was able to indirectly use $scope but calling NonScopeLibraryFunc is still a no go.
I also tried binding
const s = angular.element(document.querySelector('#somecontroller')).scope();
const newUploadFunc = function () {
$scope.doSomething(); // Error: $scope not defined
NonScopeLibraryFunc() // Error: NonScopeLibraryFunc not defined
...better non-blocking code
}.bind(s);
s.uploadFunc = newUploadFunc;
But it also does work.
Following example of overloading an angular scope function should give you the basics of what you need.
Where you might run into issues is with any arguments that might be passed into the scope function from the view
// Non angular code
document.querySelector('button').addEventListener('click', function() {
const someVar = 'Local var text';
// get angular scope
const angScope = angular.element(document.querySelector('#ang-app')).scope()
console.log('Remote access $scope.txt = ', angScope.txt);
// store reference to original scope function
const oldFunc = angScope.func
// overload original function
angScope.func = function(){
// modify scope variable with local value
angScope.txt = someVar;
// call original scope function
oldFunc();
// if modifying the original scope that needs to be changed in view use $.apply()
angScope.$apply()
}
angScope.func();
});
// Angular app
angular.module('myApp', [])
.controller('main', function($scope) {
$scope.txt = 'Scope text';
$scope.func = function(){
console.log('controller func() called')
$scope.log()
}
$scope.log = function(){
console.log('Scope txt:', $scope.txt);
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<button>Trigger modified scope func</button>
<div id="ang-app" ng-app="myApp" ng-controller="main">
Angular display: {{txt}}
</div>
I have angular 1.4 app. Im using require.js. An included script have this:
define(['firstFactory', 'secondFactory'],
function(firstFactory, secondFactory){
var app = angular.module('services', []);
app.factory('firstFactory', firstFactory);
app.factory('secondFactory', secondFactory);
});
Inside require.config (in main.js) I have path to both the factories:
"firstFactory" : "factory/firstFactory",
"secondFactory" : "factory/secondFactory"
Finally in my main controller I have this:
function myCtrl(firstFactory, secondFactory) {
Thing is that in firstFactory.js I have this code:
define([], function () {
console.log('inside define firstFactory');
var firstFactory = function () {
console.log('inside function firstFactory');
};
return firstFactory;
});
While in the secondFactory.js I have this:
define([], function () {
console.log('inside define secondFactory');
var secondFactory = function () {
console.log('inside function secondFactory');
};
return firstFactory;
});
In the console I see:
inside define firstFactory
inside function firstFactory
inside define secondFactory
So I dont see
inside function secondFactory
Why? To me the symptom is that angular is not instantiating the second factory. I cannot understand that for the first one it is being instantiated but not for the second, as Im doing the same thing with both. Any clue?
In the secondFactory.js you are returning firstFactory, may be this is the reason.
I'm trying all the approaches passing data between controllers using service, factory or broadcast. None of them works for me. I follow the exact solution online, but still unfortunate. I placed service inside my app.js.
App.JS
myApp.service('customService', [function () {
this.list = [];
this.setObject = function (o) {
this.list.push(o);
},
this.getObject = function () {
return this.list;
}
}]);
Controller #1
myApp.controller('Controller1', function ($scope, customService) {
customService.setObject({..});
$window.open("/controller2", '_blank');
}
Controller #2
myApp.controller('Controller2', function ($scope, customService) {
console.log(customService.getObject()); // Returns []
}
Problem
It returns [] on controller 2 from controller 1, instead of object data.
You should modify your service for storing a object under some specific key, and then retrieve it later given that key. You can define these keys whatever you like. I defined them in the same service so I can reuse them through all controllers. Something like this
Service
myApp.service('customService', [function () {
this.keys = {"foo": "foo", "bar": "bar"};
this.list = {};
this.setObject = function (obj, key) {
this.list[ley] = obj;
},
this.getObject = function (key) {
return this.list[key];
}
}]);
Controller #1
myApp.controller('Controller1', function ($scope, customService) {
customService.setObject({"propX": "propX"}, customService.foo);
//$window.open("/controller2", '_blank');
/* I encourage you to use something like ngRoute here for navigating
* so, you should do something like $location.path('/controller2');
*/
}
Controller #2
myApp.controller('Controller2', function ($scope, customService) {
console.log(customService.getObject(customService.foo));
}
Are your controllers in the same page ?
Angular.js only works and keeps data on a single page. If your page reloads
(as you seem to indicate when you say "express.js loads the next
page", then it reinitialized everything.
You should either:
look at how to use Angular.js routing
(http://docs.angularjs.org/tutorial/step_07) so that you stay on the
same page. use something to persist your data, such as localstorage.
Find out more: http://diveintohtml5.info/storage.html
ref : Using angular service to share data between controllers
have you used routing? if u use then your code should be work.
I have set up two controllers (Controller A and Controller B) and a service (Service). I am attempting to sync the data from controller A to the service, and present that information to Controller B.
Within my Service, I've established a variable confirmdata and get and set functions:
function setData(data) {
confirmdata = angular.copy(data);
}
function getData() {
return confirmdata;
}
In controller A I've created a function syncto sync information from the controller to the service:
this.sync = function () {
var data = {
payment: this.getpayment()
}
Service.setData(data);
In controller B I've assigned a function as:
this.sync = function () {
this.viewData = Service.getData();
console.log('TestingData', this.viewData);
For a reason I am unaware of; my console log simply returns undefined when it should be returning the results of the getpayment() function. Am I missing something here?
The fact that you are getting undefined would indicate that you haven't initialized 'confirmdata' in your service. Whether this is the actual issue though, isn't clear. For a simple example, I would design your service like this:
myApp.factory('sharedService', [function () {
var confirmdata = {};
return {
setData: function (newData) { confirmdata = newData; },
getData: function getData() { return confirmdata; }
}
}]);
Take a look at this plunker. It gives an example of data being shared between controllers via a service.
I'm having some basic problems with angular at the moment. I just wrote a service that reads the temperature of an external device in an interval of five seconds. The service saves the new temperature into a variable and exposes it via a return statement. This looks kind of this (simplified code):
angular.service("tempService", ["$interval", function ($interval) {
//revealing module pattern
var m_temp = 0,
requestTemp = function() {//some logic here},
onResponseTemp = function (temp) {
m_temp = temp;
},
//some other private functions and vars ...
foo = bar;
//request new temperture every 5s, calls onResponseTemp after new data got received
$interval(requestTemp, 5000);
return {
getTemp = function(){return m_temp;}
}
}]);
I use a controller to fetch the data from the service like this:
angular.controller("tempCtrl", ["$scope", "tempService", function ($scope, tempService) {
$scope.temp = tempService.getTemp();
}]);
In my view I access it like this:
<div ng-controller="tempCtrl">
<p>{{temp}}</p>
</div>
But I only get 0 and the value never changes. I have tried to implement a custom Pub/Sub pattern so that on a new temperature my service fires an event that my controller is waiting for to update the temperature on the scope. This approach works just fine but I'm not sure if this is the way to go as angular brings data-binding and I thought something this easy had to work by itself ;)
Help is really appreciated.
Please see here http://jsbin.com/wesucefofuyo/1/edit
var app = angular.module('app',[]);
app.service("tempService", ["$interval", function ($interval) {
//revealing module pattern
var m_temp = {
temp:0,
time:null
};
var requestTemp = function() {
m_temp.temp++;
m_temp.time = new Date();
};
var startTemp = function() {
$interval(requestTemp, 3000);
};
return {
startTemp :startTemp,
m_temp:m_temp
};
}]);
app.controller('fCtrl', function($scope,tempService){
$scope.temp = tempService;
$scope.temp.startTemp();
});
You are returning a primitive from your service, if you want to update an primative you need to reftech it. You should return an object, as on object is passed by reference, you get the actual values in your controller.
do this in your service:
return m_temp;
And this in your controller:
$scope.temp = tempService;
and your view will update as soon as the service gets updated.
Does this help you?
i think you should use $interval in controller ot in service
$interval(tempService.getTemp(), 5000);