Posts

Showing posts with the label Angularjs

Angular 1.6.0: "Possibly Unhandled Rejection" Error

Answer : Try adding this code to your config. I had a similar issue once, and this workaround did the trick. app.config(['$qProvider', function ($qProvider) { $qProvider.errorOnUnhandledRejections(false); }]); The code you show will handle a rejection that occurs before the call to .then . In such situation, the 2nd callback you pass to .then will be called, and the rejection will be handled. However , when the promise on which you call .then is successful, it calls the 1st callback. If this callback throws an exception or returns a rejected promise, this resulting rejection will not be handled , because the 2nd callback does not handle rejections in cause by the 1st. This is just how promise implementations compliant with the Promises/A+ specification work, and Angular promises are compliant. You can illustrate this with the following code: function handle(p) { p.then( () => { // This is never caught. throw new Error(...

Clear Selected Option In Ui-select Angular

Answer : If you are using the select2 theme there is an allow-clear option on the ui-select-match directive that does this for you. You will have the x on the right and you can clear it by clicking it. https://github.com/angular-ui/ui-select/wiki/ui-select-match Quick example: <ui-select-match allow-clear="true" placeholder="Select or search a country in the list..."> <span>{{$select.selected.name}}</span> </ui-select-match> Working example: http://plnkr.co/edit/DbbUE68QlNLjx97pBZ56?p=preview This does not currently work using either the bootstrap or selectize theme. You could add a small X button when you display the selection. <ui-select-match placeholder="Select or search a country in the list..."> <span>{{$select.selected.name}}</span> <button class="clear" ng-click="clear($event)">X</button> </ui-select-match> Then you stop the click event from bubb...

AngularJS : Difference Between The Observe And Observeandwatch Methods

Answer : $observe() is a method on the Attributes object, and as such, it can only be used to observe/watch the value change of a DOM attribute. It is only used/called inside directives. Use $observe when you need to observe/watch a DOM attribute that contains interpolation (i.e., {{}}'s). E.g., attr1="Name: {{name}}" , then in a directive: attrs.$observe('attr1', ...) . (If you try scope.$watch(attrs.attr1, ...) it won't work because of the {{}}s -- you'll get undefined .) Use $watch for everything else. $watch() is more complicated. It can observe/watch an "expression", where the expression can be either a function or a string. If the expression is a string, it is p a r s e ′ d ( i . e . , e v a l u a t e d a s a n A n g u l a r e x p r e s s i o n ) i n t o a f u n c t i o n . ( I t i s t h i s f u n c t i o n t h a t i s c a l l e d e v e r y d i g e s t c y c l e . ) T h e s t r i n g e x p r e s s i o n c a n n o t c o n t a ...

Angularjs Directives Isolated Scope + One-way Data-binding Not Working For Objects?

Answer : passing text is one-way binding(@) and passing object is two-way binding(=) passing object as text <custom-directive config="{{config}}"></custom-directive> scope in directive scope: { config: "@" } converting the string back to object in link var config = angular.fromJson(scope.config); You are correct, the issue is that your JavaScript objects are being passed by reference. Using a one-way binding copies the reference, but the reference will still point to the same object. My impression from the Angular docs for directives has always been: The '@' binding is intended for interpolated strings The '=' binding is intended for structured data that should be shared between scopes The '&' binding is intended for repeatedly executing an expression that is bound to the parent scope If you want to treat the bound object from the parent as immutable, you can create a deep copy the objects inside y...

AngularJS Ng-class Multiple Conditions With OR Operator

Answer : Try this. <a href="" ng-click="addFavorite(myfav.id);favorite=!favorite"> <i class="fa orange" ng-class="{'fa-star': favorite || fav==myfav.id, 'fa-star-o': !favorite}"></i> No need the brackets. Once you have to add some logic behind ng-class it's always better to stick to using the controller to do that. You can do it two of either ways: JSON syntax (same as in your HTML, just more readable) or obviously JavaScript. HTML (JSON) Syntax HTML <i ng-class="getFavClassIcon(myFav.id)"></i> JS $scope.getFavClassIcon= function (favId) { return { 'fa-star-o' : !$scope.favorite, 'fa-star' : $scope.favorite || $scope.fav === favId }; }; Good Old IF-statement (JavaScript) HTML <i ng-class="getFavClassIcon(myFav.id)"></i> JS $scope.getFavClassIcon= function (favId) { if (!$scope.favori...

AngularJS 'scrollTop' Equivalent?

Answer : $window.pageYOffset This is property from service $window I don't believe there's anything in Angular to get the scroll position. Just use plain vanilla JS. You can retrieve the scrollTop property on any element. https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollTop document.body.scrollTop Fiddle for you: http://jsfiddle.net/cdwgsbq5/ Inject the $window into your controller and you can get the scroll position on scroll var windowEl = angular.element($window); var handler = function() { console.log(windowEl.scrollTop()) } windowEl.on('scroll', handler); Fiddle Adaptation from another stackoverflow answer

AngularJS : Ng-model Binding Not Updating When Changed With JQuery

Answer : Angular doesn't know about that change. For this you should call $scope.$digest() or make the change inside of $scope.$apply() : $scope.$apply(function() { // every changes goes here $('#selectedDueDate').val(dateText); }); See this to better understand dirty-checking UPDATE : Here is an example Just use; $('#selectedDueDate').val(dateText).trigger('input'); I have found that if you don't put the variable directly against the scope it updates more reliably. Try using some "dateObj.selectedDate" and in the controller add the selectedDate to a dateObj object as so: $scope.dateObj = {selectedDate: new Date()} This worked for me.

AngularJS : When To Use Service Instead Of Factory

Image
Answer : Explanation You got different things here: First: If you use a service you will get the instance of a function (" this " keyword). If you use a factory you will get the value that is returned by invoking the function reference (the return statement in factory). ref: angular.service vs angular.factory Second: Keep in mind all providers in AngularJS (value, constant, services, factories) are singletons! Third: Using one or the other (service or factory) is about code style. But, the common way in AngularJS is to use factory . Why ? Because "The factory method is the most common way of getting objects into AngularJS dependency injection system. It is very flexible and can contain sophisticated creation logic. Since factories are regular functions, we can also take advantage of a new lexical scope to simulate "private" variables. This is very useful as we can hide implementation details of a given service." ( ...

AngularJS Paging With $location.path But No NgView Reload

Answer : Instead of updating the path, just update query param with a page number. set your route to ignore query param changes: .... $routeProvider.when('/foo', {..., reloadOnSearch: false}) .... and in your app update $location with: ... $location.search('page', pageNumber); ... From this blog post: by default all location changes go through the routing process, which updates the angular view. There’s a simple way to short-circuit this, however. Angular watches for a location change (whether it’s accomplished through typing in the location bar, clicking a link or setting the location through $location.path() ). When it senses this change, it broadcasts an event, $locationChangeSuccess , and begins the routing process. What we do is capture the event and reset the route to what it was previously. function MyCtrl($route, $scope) { var lastRoute = $route.current; $scope.$on('$locationChangeSuccess', function(event)...

AngularJS $broadcast With Multiple Parameters

Answer : Just put the parameters into an object: $scope.$broadcast('event', { a: item1, b: item2 }) Then access them from the second argument to the callback: $scope.$on('event', function(event, opt) { // access opt.a, opt.b }); Or if using ES2015 syntax you can unpack the arguments: $scope.$on('event', (event, {a,b}) => { // access them just as a, b }); Documentation says: 'Optional one or more arguments which will be passed onto the event listeners' $rootScope.$emit(event_name, p1, p2, p3);

AngularJS: How To Clear Query Parameters In The URL?

Answer : I use $location.search('key', null) As this not only deletes my key but removes it from the visibility on the URL. I ended up getting the answer from AngularJS forum. See this thread for details The link is to a Google Groups thread, which is difficult to read and doesn't provide a clear answer. To remove URL parameters use $location.url($location.path()); To remove ALL query parameters, do: $location.search({}); To remove ONE particular query parameter, do: $location.search('myQueryParam', null);

Adding Http Headers To Window.location.href In Angular App

Answer : When you use $window.location.href the browser is making the HTTP request and not your JavaScript code. Therefore, you cannot add a custom header like Authorization with your token value. You could add a cookie via JavaScript and put your auth token there. The cookies will automatically be sent from the browser. However, you will want to review the security implications of using a cookie vs. a header. Since both are accessible via JavaScript, there is no additional attack vector there. Unless you remove the cookie after the new page loads, there may be a CSRF exploit available. This answer is NOT a safe way, as the token is exposed in the URL, which is logged in browser history, access logs, etc. Use a domain cookie instead. I'll leave the answer as it can be an easy way to debug in your local setup. I am using JWT as authentication on a Laravel PHP backend, and it works by putting ?token=... in the URL. For example, when using AngularJS with satellizer plug...

Angular UI Bootstrap Vertical Tabs

Answer : Another solution is to create something like this <div class="row"> <div class="col-sm-3"> <ul class="nav nav-tabs nav-stacked nav-pills" role="tablist"> <li ng-class="{'active': view_tab == 'tab1'}"> <a class="btn-lg" ng-click="changeTab('tab1')" href="">My Tab 1</a> </li> <li ng-class="{'active': view_tab == 'tab2'}"> <a class="btn-lg" ng-click="changeTab('tab2')" href="">My Tab 2</a> </li> </ul> </div> <div class="col-sm-9"> <div class="tab-content"> <div class="tab-pane" ng-show="view_tab == 'tab1'"> This is tab 1 content </div> <div class="tab-p...

AngularJS: How To Implement A Simple File Upload With Multipart Form?

Answer : A real working solution with no other dependencies than angularjs (tested with v.1.0.6) html <input type="file" name="file" onchange="angular.element(this).scope().uploadFile(this.files)"/> Angularjs (1.0.6) not support ng-model on "input-file" tags so you have to do it in a "native-way" that pass the all (eventually) selected files from the user. controller $scope.uploadFile = function(files) { var fd = new FormData(); //Take the first selected file fd.append("file", files[0]); $http.post(uploadUrl, fd, { withCredentials: true, headers: {'Content-Type': undefined }, transformRequest: angular.identity }).success( ...all right!... ).error( ..damn!... ); }; The cool part is the undefined content-type and the transformRequest: angular.identity that give at the $http the ability to choose the right "content-type" and manage the bounda...

Angular JS Break ForEach

Image
Answer : The angular.forEach loop can't break on a condition match. My personal advice is to use a NATIVE FOR loop instead of angular.forEach . The NATIVE FOR loop is around 90% faster then other for loops. USE FOR loop IN ANGULAR: var numbers = [0, 1, 2, 3, 4, 5]; for (var i = 0, len = numbers.length; i < len; i++) { if (numbers[i] === 1) { console.log('Loop is going to break.'); break; } console.log('Loop will continue.'); } There's no way to do this. See https://github.com/angular/angular.js/issues/263. Depending on what you're doing you can use a boolean to just not going into the body of the loop. Something like: var keepGoing = true; angular.forEach([0,1,2], function(count){ if(keepGoing) { if(count == 1){ keepGoing = false; } } }); please use some or every instances of ForEach, Array.prototype.some: some is much the same as forEach but it break when the callback returns true Array.prototype.e...

AngularJS $on Event Handler Trigger Order

Answer : Very good question. Event handlers are executed in order of initialization. I haven't really thought about this before, because my handlers never needed to know which one run first, but by the look of you fiddle I can see that the handlers are called in the same order in which they are initialized. In you fiddle you have a controller controllerA which depends on two services, ServiceA and ServiceB : myModule .controller('ControllerA', [ '$scope', '$rootScope', 'ServiceA', 'ServiceB', function($scope, $rootScope, ServiceA, ServiceB) {...} ] ); Both services and the controller define an event listener. Now, all dependencies need to be resolved before being injected, which means that both services will be initialized before being injected into the controller. Thus, handlers defined in the services will be called first, because service factories are initialized before contro...

Angular Ng-if="" With Multiple Arguments

Answer : It is possible. <span ng-if="checked && checked2"> I'm removed when the checkbox is unchecked. </span> http://plnkr.co/edit/UKNoaaJX5KG3J7AswhLV?p=preview For people looking to do if statements with multiple 'or' values. <div ng-if="::(a || b || c || d || e || f)"><div> Just to clarify, be aware bracket placement is important! These can be added to any HTML tags... span, div, table, p, tr, td etc. AngularJS ng-if="check1 && !check2" -- AND NOT ng-if="check1 || check2" -- OR ng-if="(check1 || check2) && check3" -- AND/OR - Make sure to use brackets Angular2 + *ngIf="check1 && !check2" -- AND NOT *ngIf="check1 || check2" -- OR *ngIf="(check1 || check2) && check3" -- AND/OR - Make sure to use brackets It's best practice not to do calculations directly within ngIfs, so assign the variables within yo...

AngularJS Loading Progress Bar

Answer : For a progress bar as YouTube has, you can take a look at ngprogress. Then just after the configuration of your app (for example), you can intercept route's events. And do something like: app.run(function($rootScope, ngProgress) { $rootScope.$on('$routeChangeStart', function() { ngProgress.start(); }); $rootScope.$on('$routeChangeSuccess', function() { ngProgress.complete(); }); // Do the same with $routeChangeError }); Since @Luc's anwser ngProgress changed a bit, and now you can only inject ngProgressFactory , that has to be used to create ngProgress instance. Also contrary to @Ketan Patil's answer you should only instantiate ngProgress once : angular.module('appRoutes', ['ngProgress']).run(function ($rootScope, ngProgressFactory) { // first create instance when app starts $rootScope.progressbar = ngProgressFactory.createInstance(); $rootScope.$on("$routeChangeStart", function (...

Can You Resolve An Angularjs Promise Before You Return It?

Answer : Short answer: Yes, you can resolve an AngularJS promise before you return it, and it will behave as you'd expect. From JB Nizet's Plunkr but refactored to work within the context of what was originally asked (i.e. a function call to service) and actually on site. Inside the service... function getSomething(id) { // There will always be a promise so always declare it. var deferred = $q.defer(); if (Cache[id]) { // Resolve the deferred $q object before returning the promise deferred.resolve(Cache[id]); return deferred.promise; } // else- not in cache $http.get('/someUrl', {id:id}).success(function(data){ // Store your data or what ever.... // Then resolve deferred.resolve(data); }).error(function(data, status, headers, config) { deferred.reject("Error: request returned status " + status); }); return deferred.promise; } Inside the ...

AngularJS: Resolve In RouteProvider - Detecting Success / Failure?

Answer : You can just return the return value of the then method: resolve: { resolvedData: function(Restangular){ return Restangular.one('Items').get().then(function (data) { ... return successData; // resolvedData will be resolved with the successData }, function () { ... return failureData; // resolvedData will be resolved with the failureData }); } } The then method doc: This method returns a new promise which is resolved or rejected via the return value of the successCallback or errorCallback. If the resolve function fail, you will probably want to display to the user something accordingly (like an error message). It would be better to let your resolve function return a promise (without then ) and use the internal event $routeChangeError . myApp.run(['$rootScope',function($rootScope) { $rootScope.$on('$routeChangeError', function() { // what you w...