How can I use Angular JS data inside JavaScript(Google Chart)? - javascript

I want to use my angular JS scope data inside my google chart or JavaScript
My angular JS file given below
angular.module('reports').controller('ReportInfoCtrl', ['$scope', 'reports', '$rootScope','$location','blockUI',
function ($scope, reports, $rootScope, $location, blockUI) {
$scope.getReportDetail = function () {
blockUI.start();
reports.getReportInformation().then(function (data) {
blockUI.stop();
if (data !== undefined) {
$scope.report_details = data;
}
});
};
}]);

Yes, sure. You can access your scope variable of controller out side your angular.
var controllerElement = document.querySelector('[ng-controller="ReportInfoCtrl"]'); // You can use javascript or Jquery to select the controller's div element.
var controllerScope = angular.element(controllerElement).scope(); // Angular provided the interface to access angular's scope
var asd = controllerScope.report_details; // Now you can access all scope variable using 'controllerScope'
Update
angular.module('reports').controller('ReportInfoCtrl', ['$scope', 'reports', '$rootScope','$location','blockUI',
function ($scope, reports, $rootScope, $location, blockUI) {
$scope.getReportDetail = function () {
blockUI.start();
reports.getReportInformation().then(function (data) {
blockUI.stop();
if (data !== undefined) {
$scope.report_details = data;
}
return data;
});
};
}]);
And in your js file,
var asd = controllerScope.getReportDetail();

Asynchronous scope manipulations must occur within a $scope.apply to be noticed by angular.

Related

Accessing $scope data from view to factory in AngularJs

How can I access $scope data from view to my factory in angularjs? I can access $scope.items from my controller, but when I need to use it in my factory to use the data and generate a pdf I cannot access it.
angular.module('myApp', [])
.controller('myCtrl', function($scope, $http, testFactory) {
$scope.link = "http://localhost:3450/loading.html";
testFactory.all().then(
function(res){
$scope.link = res;
},
function(err){
console.log(err);
}
);
})
.factory('testFactory', function($q){
var pdfInfo = {
content: [
//data should be here...
]
};
var link = {};
function _all(){
var d = $q.defer();
pdfMake.createPdf(pdfInfo).getDataUrl(function(outputDoc){
d.resolve(outputDoc);
});
return d.promise;
}
link.all = _all;
return link;
});
I used factory when I click the generate button from my view, it will wait until the pdf is generated. Coz when I did not do it this way before, I need to click the button twice just to get the pdf generated.
You can just pass the data to your factory as a
function parameter.
angular.module('myApp', [])
.controller('myCtrl', function($scope, $http, testFactory) {
var pdfInfo = {
content: $scope.items
};
$scope.link = "http://localhost:3450/loading.html";
testFactory.all(pdfInfo).then(
function(res) {
$scope.link = res;
},
function(err) {
console.log(err);
}
);
})
.factory('testFactory', function($q) {
var link = {};
function _all(pdfInfo) {
var d = $q.defer();
pdfMake.createPdf(pdfInfo).getDataUrl(function(outputDoc) {
d.resolve(outputDoc);
});
return d.promise;
}
link.all = _all;
return link;
});
I did it. I forgot to send the $scope.items to my factory. So what i did is I added testFactory.all($scope.items) in my controller instead of just plain testFactory.all().
Then in my factory,
I used function _all(value), so I can used the values passed by the views through controller. I am not sure if this is the proper way, but it works. Please suggest good practice if you have.
It is a bad practice to move around $scope to other services, as they may change it and effect your controller logic. It will make a coupling between controllers to other services.
If your factory requires data from the controller, it is better to just pass those parameters to the factory's function.
EDIT: I see you managed to do that, and yes - passing $scope.items is the preferred way (and not, for example, passing $scope).

AngularJs: pass $scope variable with service

I have two controllers and in one of them I declared a $scope variable that I would like visible in the second controller.
First controller
app.controller('Ctrl1', function ($scope) {
$scope.variable1 = "One";
});
Second Controller
app.controller('Ctrl2', function ($scope, share) {
console.log("shared variable " + share.getVariable());
});
I researched the best Angular approach and I found that is the use of service. So I added a service for Ctrl1
Service
.service('share', function ($scope) {
return {
getVariable: function () {
return $scope.variable1;
}
};
});
This code return this error:
Unknown provider: $scopeProvider <- $scope <- share
So my question is: is possible share $scope variable between controllers? Is not the best Angular solution or i'm missing something?
Sorry for my trivial question but I'm an Angular beginner.
Thanks in advance
Regards
Yes, it is possible to share the scope variables between controllers through services and factory.But, the $scope variables are local to the controller itself and there is no way for the service to know about that particular variable.I prefer using factory, easy and smooth as butter. If you are using the service of factory in a separate file you need to include the file in index.html
app.controller('Ctrl1', function ($scope,myService,$state) {
$scope.variable1 = "One";
myService.set($scope.variable1);
$state.go('app.thepagewhereyouwanttoshare');//go to the page where you want to share that variable.
});
app.controller('Ctrl2', function ($scope, myService) {
console.log("shared variable " + myService.get());
});
.factory('myService', function() {
function set(data) {
products = data;
}
function get() {
return products;
}
return {
set: set,
get: get
}
})
You cannot inject $scope dependency in service factory function.
Basically shareable service should maintain shareable data in some object.
Service
.service('share', function () {
var self = this;
//private shared variable
var sharedVariables = { };
self.getSharedVariables = getSharedVariables;
self.setVariable = setVariable;
//function declarations
function getSharedVariables() {
return sharedVariables;
}
function setVariable() {
sharedVariables[paramName] = value;
}
});
Controller
app.controller('Ctrl1', function ($scope, share) {
$scope.variable1 = "One";
share.setVariable('variable1', $scope.variable1); //setting value in service variable
});
app.controller('Ctrl2', function ($scope, share) {
console.log("shared variable " + share.getSharedVariables());
});
Your try with service it quite good, but you shouldn't try to use $scope in dependency injection into the service code. Service is meant to be a data provider to you, then if you want to share some data between 2 controllers, you should make place for this data in your service
.service('share', function ($scope) {
this.variable1 = '';
return {
getVariable: function () {
return this.variable1;
}
setVariable(variable)
{
this.variable1 = variable;
}
};
});
app.controller('Ctrl1', function (share) {
$scope.variable1 = share.getVariable();
});
This is the broader description of this solution:
https://stackoverflow.com/a/21920241/4772988
Best way is really using services. Services have only access to $rootScope, they don't have their own $scope.
However, you shouldn't use scopes for this task. Just make a service with some shared variable outside any scopes.
.service('share', function ($scope) {
var variable = 42;
return {
getVariable: function () {
return variable;
}
};
});
app.controller('Ctrl', function ($scope, share) {
console.log("shared variable " + share.getVariable());
// Watch for changes in the service property
$scope.$watch(function() { return share.getVariable(); }, function(oldValue, newValue) {
// whatever
});
});
First, your service should be like this:
app.service('share', function () {
// this is a private variable
var variable1;
return {
// this function get/sets the value of the private variable variable1
variable1: function (newValue) {
if(newValue) variable1 = newValue;
return variable1;
}
};
});
To set the value of the shared variable pass the value to the function we created on the service
app.controller('Ctrl1', function ($scope, share) {
$scope.variable1 = "One";
// share the value of $scope.variable1
share.variable1($scope.variable1);
});
To get the value of the shared variable also use the function in the service without passing a value
app.controller('Ctrl2', function ($scope, share) {
console.log("shared variable " + share.variable1());
});
Update: Using $rootScope is considered bad practice.
What you need is the $rootScope. The $scope is just for one controller. Here is an example:
angular.module('myApp', [])
.run(function($rootScope) {
$rootScope.test = new Date();
})
.controller('myCtrl', function($scope, $rootScope) {
$scope.change = function() {
$scope.test = new Date();
};
$scope.getOrig = function() {
return $rootScope.test;
};
})
.controller('myCtrl2', function($scope, $rootScope) {
$scope.change = function() {
$scope.test = new Date();
};
$scope.changeRs = function() {
$rootScope.test = new Date();
};
$scope.getOrig = function() {
return $rootScope.test;
};
});

AngularJS: How to share scope functions and variables with other controllers

I've multiple controllers in my application, where I have some duplicate code like:
$scope.alert = null;
$scope.addAlert = function (message) {
$scope.alert = { type: 'danger', msg: message };
};
$scope.clearAlerts = function () {
$scope.alert = null;
};
What is the recommended way sharing these scope functions and variables in AngularJS? Using controller inheritance?
Create a one controller and then place common methods inside that controller scope. So that you can use that scope anywhere else and get access to method inside controller.
Controller
app.controller('commonCtrl', function($scope) {
$scope.alert = null;
$scope.addAlert = function(message) {
$scope.alert = {
type: 'danger',
msg: message
};
};
$scope.clearAlerts = function() {
$scope.alert = null;
};
});
Thereafter use scope of this controller by inject it using $controller, and then inside curly brace you could assign common controller scope to the current scope of controller.
Utilization of Common Controller
app.controller('testCtrl', function($scope, $controller) {
//inject comomon controller scope to current scope ,
//below line will add 'commonCtrl' scope to current scope
$controller('commonCtrl', { $scope: $scope });
//common controller scope will be available from here
});
Or more precise way would be using common sharable service, that exposed two method and alert data, you can use this service method by injecting service name inside your controller.
Service
app.service('commonService', function($scope) {
this.alert = null;
this.addAlert = function(message) {
this.alert = {
type: 'danger',
msg: message
};
};
this.clearAlerts = function() {
this.alert = null;
};
});
Utilization of service inside Controller
app.controller('testCtrl', function($scope, commonService) {
console.log(commonService.alert);
commonService.addAlert("Something");
console.log("Updated Alert" + commonService.alert);
});
Hope this has cleared your concept, Thanks.
My own solution for this use case was to define a type of Observer Pattern.
The code was structured in the following way:
var app = angular.module('testModule', []);
app.factory('alertService', ['$timeout', function($timeout){
var alertListeners = [];
this.register = function (listener) {
alertListeners.push(listener);
};
this.notifyAll = function (data) {
for (// each listener in array) {
var listenerObject = alertListeners[i];
try { // do not allow exceptions in individual listeners to corrupt other listener processing
listenerObject.notify(data);
} catch(e) {
console.log(e);
}
}
};
}]).
directive('myAlerts', ['alertService', function(alertService){
var alertDirectiveObserver = function($scope, alertService) {
this.notify = function(data) {
/*
* TO DO - use data to show alert
*/
};
/*
* Register this object as an event Listener. Possibly supply an event key, and listener id to enable more resuse
*/
alertService.register(this);
$scope.on('$destroy', function() {
alertService.unregister(// some listener id);
});
};
return {
restrict: 'A',
template: '<div ng-class="alertClass" ng-show="alertNeeded">{{alertMessage}}</div>',
controller: ['$scope', 'alertService', alertDirectiveObserver],
link: function(scope){
}
}
}]).
controller('alertShowingController', ['$scope', 'alertService', function($scope, alertService){
alertService.notifyAll({'warning', 'Warning alert!!!'})
]);
The alertShowingController is a simple example of how all controllers can simply inject the alertService and generate an event.
My own implementation is more elaborate in that it uses separate event keys to allow the controllers to generate other event notifications.
I could then define a single div that was in a fixed position at the top of the page that would dispay bootstrap alerts.
<div my-alerts ng-repeat="alert in alertList" type="{{alert.type}}" close="closeAlert(alertList, $index)">{{alert.msg}}</div>

$scope is undefined in Controller

I have the worlds simplest controller which i want access to $scope but it is "undefined" and I cannot, for the life of me work out why, however all the functions are called corectly, the DataService, etc is working perfectly, just i have no access to $scope?!
controller code is below
app = angular.module("windscreens", []);
app.controller('DamageCtrl', function($scope, DataService) {
$scope.setDamageLocation = function(location) {
DataService.getDamage().setLocation(location);
};
$scope.isLocation = function(requiredLocation) {
return DataService.getDamage().getLocation() === requiredLocation;
};
$scope.progress = function() {
};
});
To access a property on the scope from your HTML template you only need to use the property name, you don't need to write $scope with it.
Example:
<button ng-click="progress()"></button>
In your javascript you will only have access to the $scope inside the controller and its functions. If you call an external resource, for example: DataService module, it won't have access to the $scope unless you pass it as an argument explicitly.
I managed to get it working using the alternative syntax. As detailed below, still not sure why it wasn't working but hey hum
app.controller('DamageCtrl', ['$scope', 'DataService',
function($scope, DataService) {
$scope.setDamageLocation = function(location) {
DataService.getDamage().setLocation(location);
};
$scope.isLocation = function(requiredLocation) {
return DataService.getDamage().getLocation() === requiredLocation;
};
$scope.progress = function() {
console.log($scope);
};
}
]);

How to include/inject functions which use $scope into a controller in angularjs?

I am trying to include a library of functions, held in a factory, into a controller.
Similar to questions like this:
Creating common controller functions
My main controller looks like this:
recipeApp.controller('recipeController', function ($scope, groceryInterface, ...){
$scope.groceryList = [];
// ...etc...
/* trying to retrieve the functions here */
$scope.groceryFunc = groceryInterface; // would call ng-click="groceryFunc.addToList()" in main view
/* Also tried this:
$scope.addToList = groceryInterface.addToList();
$scope.clearList = groceryInterface.clearList();
$scope.add = groceryInterface.add();
$scope.addUp = groceryInterface.addUp(); */
}
Then, in another .js file, I have created the factory groceryInterface. I've injected this factory into the controller above.
Factory
recipeApp.factory('groceryInterface', function(){
var factory = {};
factory.addToList = function(recipe){
$scope.groceryList.push(recipe);
... etc....
}
factory.clearList = function() {
var last = $scope.prevIngredients.pop();
.... etc...
}
factory.add = function() {
$scope.ingredientsList[0].amount = $scope.ingredientsList[0].amount + 5;
}
factory.addUp = function(){
etc...
}
return factory;
});
But in my console I keep getting ReferenceError: $scope is not defined
at Object.factory.addToList, etc. Obviously I'm guessing this has to do with the fact that I'm using $scope in my functions within the factory. How do I resolve this? I notice that in many other examples I've looked at, nobody ever uses $scope within their external factory functions. I've tried injecting $scope as a parameter in my factory, but that plain out did not work. (e.g. recipeApp.factory('groceryInterface', function(){ )
Any help is truly appreciated!
Your factory can't access your $scope, since it's not in the same scope.
Try this instead:
recipeApp.controller('recipeController', function ($scope, groceryInterface) {
$scope.addToList = groceryInterface.addToList;
$scope.clearList = groceryInterface.clearList;
$scope.add = groceryInterface.add;
$scope.addUp = groceryInterface.addUp;
}
recipeApp.factory('groceryInterface', function () {
var factory = {};
factory.addToList = function (recipe) {
this.groceryList.push(recipe);
}
factory.clearList = function() {
var last = this.prevIngredients.pop();
}
});
Alternatively, you can try using a more object oriented approach:
recipeApp.controller('recipeController', function ($scope, groceryInterface) {
$scope.groceryFunc = new groceryInterface($scope);
}
recipeApp.factory('groceryInterface', function () {
function Factory ($scope) {
this.$scope = $scope;
}
Factory.prototype.addToList = function (recipe) {
this.$scope.groceryList.push(recipe);
}
Factory.prototype.clearList = function() {
var last = this.$scope.prevIngredients.pop();
}
return Factory;
});
You cannot use $scope in a factory as it is not defined. Instead, in your factory functions change the properties of the object the factory is returning, e.g.
factory.addToList = function (recipe) {
this.groceryList.push(recipe);
}
these will then get passed on to your $scope variable
$scope.addToList = groceryInterface.addToList;
// ... = groceryInterface.addToList(); would assign to `$scope.addToList` what is returned, instead of the function itself.
This isn't the exact answer for this question, but I had a similar issues that I solved by simply passing $scope as an argument to a function in my factory. So it won't be the normal $scope, but $scope at the time the function in the factory is called.
app.controller('AppController', function($scope, AppService) {
$scope.getList = function(){
$scope.url = '/someurl'
// call to service to make rest api call to get data
AppService.getList($scope).then(function(res) {
// do some stuff
});
}
});
app.factory('AppService', function($http, $q){
var AppService = {
getList: function($scope){
return $http.get($scope.url).then(function(res){
return res;
});
},
}
return AppService;
});

Categories