How to make a generic close button for angular ui-views? - angularjs

I need a function where I can use $window.history.back() to be called from every view regardless of what controller is controlling that page.
.run(['$rootScope', '$state', 'CommonUserModel', 'InitialiseService','$window', function($rootScope, $state, $window, commonUserModel, initialiseService) {
$rootScope.link = function(){
$window.history.back();
};
So I have this function put in the app module. Injected window object because it complained about it. But now it also complains that it "Cannot read property 'back' of undefined".
I am calling this function with $rootScope from other controllers as I read through StackOverflow. I had to inject $rootScope to other controllers like this.
homeViewModule.controller("simDetailsController", [ '$rootScope','$scope', 'ModalDialogService', 'CommonTagModel', '$location','$window',
function($scope, modalDialogService, commonTagModel, $location, $window,$rootScope) {
self.link = function(){
$rootScope.link();};
Can you give me an advice?
Keep in mind that I am pretty newbie on AngularJS I still don't get this messy, complex framework.

The order in which you have injected $window & $rootScope in the parameters list does not match the string array list.
You have mentioned '$window' as the 5th element in the string array, while, it is the 3rd element in the parameters list.
Also, in your code, '$rootScope' is the 1st element in the string array, while, it is the 6th element in the parameters list.
Replace the first lines in both of your code snippets with these:
.run(['$rootScope', '$state', 'CommonUserModel', 'InitialiseService','$window', function($rootScope, $state, commonUserModel, initialiseService, $window) {
homeViewModule.controller("simDetailsController", [ '$rootScope','$scope', 'ModalDialogService', 'CommonTagModel', '$location','$window',
function($rootScope, $scope, modalDialogService, commonTagModel, $location, $window) {

You should use routes:
https://docs.angularjs.org/api/ngRoute/service/$route

Related

Using textangular functions in angular controller?

I am new to angular and am trying to alter the default behavior of a textangular text input field on my site's backend (I am a guitarist, not a web developer, but can usually figure out what I need to do...). The field has an option to specify a youtube url and then textangular converts that to an image for purposes of editing in the backend. Then in front end textangular has means to have a youtube url displayed correctly as an iframe.
However, on the front end I am not using angular and I read that in my case, to get a youtube embed to show up in front end as iframe you have to use the taApplyCustomRenderers function.
For example, see here:
how to strip placeholder img in textAngular editor in scope var?
In my angular app, here are some of the relevant lines:
angular.module('dashboard')
.controller('EditController', ['$scope', '$http', '$location', '$routeParams', function ($scope, $http, $location, $routeParams) {
$scope.save = function () {
$scope.busy = true;
// I thoguht I could do this:
$scope.somefield = taApplyCustomRenderers($scope.somefield);
// then I would save to model
});
I am getting error that taApplyCustomRenderers is undefined. I thought based on what I read that taApplyCustomRenderers is an available function when using textangular but being new to this I suppose I am missing some key step about injecting the function into the controller or something.
Hoping someone can shed some light.
Thanks in advance!
Brian
TLDR; When you try to access taApplyCustomRenderers you are recieving an error since it is not given to this current function, Inject the function and it will work.
The Problem
While I have never actually tried using textAngular, let me explain what the problem is, and from there it should be easy to find the solution.
Your EditController is just a regular javascript function that gets run and attached to the relevant DOM element, so it only has access to functions that are declared in its own scope (or globally).
Here is your exact code just indented differently so you can understand better:
angular.module('dashboard').controller(
'EditController',
[
'$scope',
'$http',
'$location',
'$routeParams',
function ($scope, $http, $location, $routeParams) {
...
$scope.somefield = taApplyCustomRenderers($scope.somefield);
}
]
);
As you can see, the controller function has two parameters, the first being a string and the second an array, and the last element in the array is just a regular function.
The solution
Checking the textAngular documentation I saw that the taApplyCustomRenderers is a factory, which means you can inject it into your controller function as so:
angular.module('dashboard').controller('EditController',
['$scope', '$http', '$location', '$routeParams', 'taApplyCustomRenderers',
function ($scope, $http, $location, $routeParams, taApplyCustomRenderers) {
taApplyCustomRenderers(); // is now Available.
}
]);

Angularjs - Refresh Control

I am a novice, and don't fully understand functions and how/where they are called but I want to refresh a control that has buttons on it that can be enabled/disabled based on state of something else.
The state is determined when the html for that ctrl is loading.
Question is:
For this control, will the reload() command reload only the TaskCtrl, or the entire web page containing all controls? I don't want to reload the entire page.
var mainCtrl = angular.module('MyCtrl', []);
mainCtrl.controller('TaskCtrl', ['$scope', '$routeParams', '$window', '$location', '$rootScope', '$log',
function($scope, $routeParams,
$window, $location, $rootScope, $log)
{
$scope.loadStuff = function() {
.......
$scope.studyToken = ret.studyToken;
$scope.studies = ret.studies;
$window.location.reload();
}
I notice that "loadStuff" function is in another control so I'm assuming that this is a "scope" function that when it executes it can be local in other controls and perform other functions in that control when it executes?
Any suggestions on references for learning these concepts are welcome.

Different ways to initialize AngularJS Controllers? [duplicate]

I see the following angularjs controller syntax structure all the time.
angular.module('7minWorkout').controller('WorkoutController',
['$scope', '$interval', '$location',
function ($scope, $interval, $location)
{
}]);
Why the repetition in the parameter names? Why not just like this
angular.module('7minWorkout').controller('WorkoutController',
['$scope', '$interval', '$location',
function ()
{
}]);
or
angular.module('7minWorkout').controller('WorkoutController',
[
function ($scope, $interval, $location)
{
}]);
The array syntax will help you with minification/uglify of your js code.
angular.module('7minWorkout').controller('WorkoutController',
function ($scope, $interval, $location) {
// code here
});
Will be minified and mangled as:
angular.module('7minWorkout').controller('WorkoutController',
function (a, b, c) {
// code here
});
So Angular won't be able to figure out which dependencies to inject
On the other hand, using the array declaration:
angular.module('7minWorkout').controller('WorkoutController',
['$scope', '$interval', '$location', function ($scope, $interval, $location) {
// code here
}]);
Will be minified as :
angular.module('7minWorkout').controller('WorkoutController',
['$scope', '$interval', '$location', function (a, b, c) {
// code here
}]);
So Angular will know what a, b and c represent.
There's also another way to inject variables if you use your first example code like below:
WorkoutController.$inject = ['$scope', '$interval', '$location'];
or
angular.module('7minWorkout').controller('WorkoutController', /* #ngInject */
function ($scope, $interval, $location) {
// code here
});
which will create the $inject method mentioned above when the code is annotated.
So, there are mainly four kinds of annotation:
Implicit Annotation - the first example code
Inline Array Annotation - the second example code
$inject Property Annotation - the $inject method
$ngInject Comment Annotation - the #ngInject method
ng-annotate
Tools like ng-annotate let you use implicit dependency annotations in your app and automatically add inline array annotations prior to minifying. If you decide to take this approach, you probably want to use ng-strict-di.
For more information, see AngularJS Developer Guide - Using Strict Dependency Injection.
This "repetion" is to make it safe for minification:
AngularJS - Controllers, Dependencies, and Minification
or you can use following syntax, according to popular angular-styleguide https://github.com/johnpapa/angular-styleguide
angular.module('7minWorkout')
.controller('WorkoutController', WorkoutController);
WorkoutController.$inject = ['$scope', '$interval', '$location'];
function WorkoutController($scope, $interval, $location) {
}
You could write the first version since it just omits the parameters of the function which are also accesible via arguments inside the function. So you would avoid the repition but slicing the arguments property is also not really efficient (compared to just type out the parameters).
As the others answers stated the repition is to make it safe for minification.
The first controller syntax makes it possible to minify/uglify the javascript code with the use of tools like ngmin. I'm not quite sure if the 2nd and 3rd options you have provided are viable options to create a controller, but in any case they will not be minified correctly since the tools will not now what the providers are. I would either suggest to use option 1 or option 3 (without the brackets) to create a controller. Note that option 3 will not be minified correctly by automated tools.
Some Useful information about creating controllers:
AngularJS Developer Guide - Controllers
option3 without brackets
angular.module('7minWorkout').controller('WorkoutController', function ($scope, $interval, $location)
{
//Your Code
});

$timeout is not a function error

Hey guys got a little problem that i cant seem to see the problem for. Im building an angular application and im getting the error stated in the question title. Ive injected the $timeout to the controller but im still getting an error with this bit of code can some one tell me where i may be going wrong?
cheers
(function() {
'use strict';
angular
.module('my.module')
.controller('NewSearchController', NewSearchController);
NewSearchController.$inject = ['$rootScope', '$scope', '$location','UserService',
'SearchService', '$window', '$controller', '$mdDialog', 'ModalService', '$routeParams', '$timeout'];
/**
* #namespace ContactController
*/
function NewSearchController($rootScope, $scope, $location, UserService, SearchService, $window, $controller, $mdDialog, $routeParams, $timeout)
Timeout code:
var timerMax = false;
$scope.$watch(NewSearchController.searchObject.maxDayRate, function(){
if(timerMax) {
$timeout.cancel(timerMax);
}
timerMax= $timeout(function() {
NewSearchController.updateSearchFilters();
}, 5000);
});
The problem is in your injection: 'ModalService' listed as injectable but not one of the parameters so angular will inject 'ModalService' and the values you get for parameters later in the list are all wrong.
If you use something like gulp to build your app then use gulp-ng-annotate to build the injection list automatically. That way it won't go wrong and you never have to worry about it.
'$mdDialog', 'ModalService', '$routeParams', '$timeout']
$mdDialog, $routeParams, $timeout
these two dnt match Change it to
$mdDialog,ModalService, $routeParams, $timeout
you have injected $timeout at position 11th position in controller but in function it is at 10th position as u have missed ModalService in function.So the error is just because of this . You need to inject and add the dependcies at same position otherwise it wont work.

$window on ngClick directive

Why this doesn't work ?
Since angular expression doesn't have access to window object, i've used $window, however the below doesn't work.
<button ng-click="$window.alert('Hi There')">Hi There</button>
Angular expressions do not have access to global variables like
window, document or location. This restriction is intentional. It
prevents accidental access to the global state – a common source of
subtle bugs.
A template only has access to variables that are put on its $scope. If you need to access anything on $window from your template you'll need to inject $window into your controller and assign it to $scope there.
For example
angular.module('app').controller('Controller',
['$scope', '$window', function($scope, $window) {
$scope.$window = $window;
}]);
As pointed out in the comments, you probably don't want to expose the entire $window wrapper to your template so a better approach is to use a helper function on $scope.
ng-click="greet('Hi There')"
angular.module('app').controller('Controller',
['$scope', '$window', function($scope, $window) {
$scope.greet = function(message) {
$window.alert(message);
};
}]);
You can only call services in your controllers through scope (this is the idea of separating non-UI logic from the template)
See How to call a service function in AngularJS ng-click (or ng-change, ...)?
$window is a service, and like other services that don't relate directly to the view, they are not accessible in the templates.
angular.module('app').controller('Controller',
['$scope', '$window', function($scope, $window) {
$scope.alert=$window.alert
}]);

Resources