I have this external API on the global scope:
var _viewerApi = function(){
var selectedObject = null;
return {
selectObject: function(obj){
selectedObject = obj;
},
getSelectedObject: function(){
return selectedObject;
}
}
}
viewerApi = _viewerApi();
I have another external non-angular package talking with this api.
How do I attach this so angular checks the getSelectedObject? I want to fire angular events when getSelectedObject returns something
I guess I need to do a service and connect this somehow?
You can save the above code in a separate file. Export that file into the relevant js file where you want to use the service. Inject that service into the angular controller you want to use within. It will create a instance of service to be used within a controller.
Related
I need to use this NoSleep.js inside my AngularJs controller. I installed NoSleep using bower but I need to inject it to my angularjs controller, but I have no idea on how do it, NoSleep isn't an angular service and I need to use this declaration var noSleep = new NoSleep(); in order to use it.
I'm using babel, webpack, gulp, karma
Any advise?
Typically when using non-angularjs libraries in an Angularjs application they are wrapped in a module. Then you inject the module into your app and then inject the service/factory you've wrapped with this into your controllers as needed, so you'd create a module that looks something like this:
(() => {
"use strict"
angular.module('nosleep.module', []).factory('nosleep', ['', function () {
return new NoSleep()
}])
})()
Then you'd inject the module into your main application module with something like:
angular.module('myApp', '[nosleep-module')
Then in your controllers that require access to nosleep you'd inject nosleep.
class myController {
constructor(nosleep) {
this.nosleep = nosleep
}
}
Then from within your control your can address it with this.nosleep.
It looks like NoSleep just declares a function in the global scope, so you could do something like this:
NoSleepService.js
(function () {
// place noSleep minified code here
angular.module('myApp').service('noSleep', NoSleep);
})()
That will create a NoSleep object within the enclosing function so that it doesn't pollute the global scope and register a new instance of it to your angular app.
If you have any JS lib and it's not an Angularjs lib, just add it using script tag in the html file and call it like you used to before they create AngularJs.
Have you tried it ?
Or go to the other way and wrap the lib with AgnularJs service (write an AngularJs service and call the lib method inside it), then inject this new service anywhere you want.
Update:
What #Mike Feltman and #richbai90 said in their answers was good and maybe enough for you, but I think it's better to build your service and call a methods you created, but inside these method use what ever library you want (it'll be like using interfaces in C#):
(function() {
'use strict';
angular.module('nosleep.module', []).service('nosleep', ['', nosleepFunc]);
function nosleepFunc() {
var nosleepObj = new NoSleep();
var service = {
method1: method1,
method2: method2
//... etc
};
function method1() {
return nosleepObj.method1();
}
// ..... other methods
return service;
}
})();
This way if you wanted to change nosleep lib to another one, and that new one lib has another method names, you need only to change in your service code.
I'm newb to swagger , I have generated javascript-closure-angular-client from swagger-editor.
I want to used javascript-closure-angular-client in my AnuglarJS project. But I can't find any explanation for how to use it with AnuglarJS project.
Can anyone guide me for how to used javascript-closure-angular-client with AnuglarJS project?
I recommend you use swagger-js-codegen
Repository: https://github.com/wcandillon/swagger-js-codegen
And in this repository I explain how to generate the client in this case called clientAngularSwagger.js:
https://github.com/CayetanoHerreraLuisRicardo/swagger-angularjs-client
The next step would be:
To add it to your AngularJS project, do the following:
Add the generated file in the project for example:
<script src="js/models/clientAngularSwagger.js" type="text/javascript"></script>
Inject factory to controller
angular.module('App').controller('test', function ($scope, clientSwagger) {
....
}
and finally do requests to the web service in test controller
//clienSwagger object
$scope.swaggerObject = new clientSwagger("APIurl",false); //the parameter "APIurl" is optional, because in the clientSwagger factory is defined
//paramether to send
$scope.parameters = [];
$scope.parameters["authorization"]="Bearer xxxxxxxx";
$scope.parameters["xparameter"]="xxxx";
$scope.data = [];
//request function http
$scope.BBBObject.herefunctionname($scope.parameters).then(function(res)
{
$scope.data= res.data;
}, function(e) {
console.log(e);
});
There are a couple of variables I want to share between two html files and two modules. Firstly, I used the service as follows but it did not work.
In vote.js:
var vote = angular.module('vote', []);
vote.service('voteParam', function () {
this.candidates = [];
this.show_result;
this.vote_begin;
this.elec_begin;
this.setValue = function (voteParam) {
this.department = voteParam.department;
this.group = voteParam.group;
this.type = voteParam.type;
this.round = voteParam.round;
this.times = voteParam.times;
this.advance_num = voteParam.advance_num;
}
});
In vote-setting.js:
angular.module('admin')
.controller('vote_setting', function ($scope, $http, voteParam) {
$scope.begin_vote = function () {
init();
startit();
$scope.vote_begin = true;
$scope.elec_begin = true;
voteParam.vote_begin = true;
voteParam.elec_begin = true;
voteParam.show_result = false;
voteParam.setValue($scope.voteParam);
if (voteParam.candidates.length == 0) {
$scope.get_candidate();
}
};
}
When the value is set as true in vote-setting.js, it is showed as undefined in vote.js. I think it's because when I import vote-setting.js in vote-setting.html, variables in the service are initialized again. Is there any other way I can make this work?
The service worked. But the value of variables in it get initialized when the js file is imported again. This is the key of this problem. Thanks
You might want to know the following:
Generally,an angular app should have only one base module. This is the module which you add to your html using ng-app directive. So your html content will know about only one angular app.
You can however create as many other modules as you would like or need. These can be custom modules as in your case, or these can be third party library (modules written by other developers for your ready use.). In any of the above case you need to add extra modules to your base module as dependencies as shown below:
angular.module('baseModule', ['extraModule1, extraModule2]);
Once you are done with this, any component like any directive , service, factory written in any of the extra modules shall be available to you for use, as if they were all written in your baseModule.
Having said this and coming to your question, the code provided by you doesn't seem sufficient to entirely diagnose your issue. However from whatever I get, I suggest you to add vote module to admin module or vice-versa. If you have any other module as a base module, you need to add both vote and admin as dependencies to that module.
Hope this helps you to start fixing the issue. Let me know if any thing seems unclear yet.
Implement your shared data service as a factory.
Implement proper getter and setters.
Encapsulate your variables and only expose the getter, setters.
Example of shared data service (can also be used as a shared Model)
app.factory('voteParam', function() {
var param1;
var param2;
var param3;
return {
setParam1: function(value){
param1 = value;
},
getParam1: function(){
return param1;
},
setParam2: function(value){
param2 = value;
},
getParam2: function(){
return param2;
},
setParam3: function(value){
param3 = value;
},
getParam3: function(){
return param3;
}
}
});
In an application this factory should be initialized once only.
If you are using 2 different angular applications (in your case 'vote' and 'admin') then use local storage or session storage to share data between them
Im learning AngularJS and his separation of concerns using module.
I have created a simple app that is composed by an index.html that is the view, and two file .js, one for the controller and one for my own service.
The question is the following: How i can inject the .js file that contains the service, into the one for the controller?
That's my controller.js
var myApp = angular.module('myApp',[]);
myApp.controller('myController', function($scope, $window,$interval,$location) {
$scope.appUrl = $location.absUrl();
$scope.port = $location.port();
$scope.protocol = $location.protocol();
$scope.winWidth = $window.innerWidth;
$interval(function(){
$scope.winWidth = $window.innerWidth;
}, 1);
});
and this is the date-time-service.js
var service = angular.module('myApp',[]);
service.factory('dateTimeService', function() {
var dateTimeSvc = {};
dateTimeSvc.getData = function(){
return new Date().toDateString();
}
dateTimeSvc.getTime = function(){
return new Date().toTImeString();
}
return dateTimeSvc;
})
Obviosly i know that i can create a single .js file that contains both and call it into my view, but i want to understand the logic behind the dependencies injection starting with this "stupid" application, and then extends it to a little bit larger applications.
Thanks you all anticipately for all the answers!
We don't inject the js file. We inject dependencies.
If you are looking into how to dynamically inject modules in run time after angular context is initialisized -- its here http://blog.getelementsbyidea.com/load-a-module-on-demand-with-angularjs/
I have implemented this long ago where I dynamically call modules from server and inject it into my angular context based on which screen the user is in.
I'm trying to figure out how to load the contents of a JavaScript file into a scope. The reason for this is I want to be able to have plug and play capability and be able to load different functionality into my app. Perhaps the user role determines what functionality is loaded, or perhaps I want to tailor my app for a given client.
Here's an example of the contents of one of my pluggable JavaScript file:
myApp.LoginViewModel = (function ()
{
//DATA
var self = this;
return {
HelloWorld: function ()
{
alert('Hellow World from Login View Model');
}
};
})();
Here is an example of the configuration file listing what JS files should be loaded:
var myApp = myApp || {};
myApp.ViewModelRegistry =
{
BaseViewModel: { JavaScriptPath: "/Scripts/ViewModels/BaseViewModel.js"},
LoginViewModel:{ JavaScriptPath: "/Scripts/ViewModels/LoginViewModel.js"}
};
Here's my code that loops through ViewModelRegistry and uses jQuery to load the script:
InitializeApp: function ()
{
//REGISTER VIEW MODELS
for (var viewModelName in myApp.ViewModelRegistry)
{
var registeredModel = myApp.ViewModelRegistry[viewModelName];
$.getScript(registeredModel.JavaScriptPath, function (data, textStatus, jqxhr)
{
});
}
console.log(myApp);
}
};
My goal is to load the JavaScript function from the JS file into the myApp scope. Each pluggable JS file is scoped to myApp. I thought simply using jQuery's getScript to load the JS file would automatically update the myApp scope since all pluggable JS files are designed to that scope. However, the console.log(myApp) doesn't reveal the code from the JS files. What am I missing? Is this even feasible?
I believe your console.log is executed before any of your JS files have been retrieved and parsed. Other than that, you seem to be on the correct course. This is definitely feasible, and the terminology used to describe what you want to achieve is called Asynchronous Module Definitions.