Slightly new to AngularJS so please bear with me.
I'm trying to implement ngStorage but had a doubt. If I assign something like this:
$scope.$storage = $localStorage.default({
var: 'foo'
});
And then if $scope.storage.var is changed when an AJAX call is made, does it also change the value of $localStorage.var or do I have to manually re-assign it?
If I do have to manually re-assign it, what's the best way to do so among the options below? (Please do let me know if there's any other way to do it)
$localStorage.var = 'foo2';
$localStorage.$reset({
var : 'foo2'
});
delete $localStorage.var followed by $localStorage.var = 'foo2'
Thanks in advance.
I just used the third option and it seemed to work correctly. That is:
delete $localStorage.var;
$localStorage.var = 'foo2';
I'm actually doing an app for a stage, which has to be responsive design. So it has to work on Mobile, Computer and Tablet. For this app I need to use the google api Place Autocomplete. The problem with that is that it doesn't work on mobile, whether it's iOS or android... on another forum i found a piece of code which is the following, supposed to resolve this problem :
.directive('disableTap', function($timeout) {
return {
link: function() {
$timeout(function() {
// Find google places div
_.findIndex(angular.element(document.querySelectorAll('.pac-container')), function(container) {
// disable ionic data tab
container.setAttribute('data-tap-disabled', 'true');
// leave input field if google-address-entry is selected
container.onclick = function() {
document.getElementById('autocomplete').blur();
};
});
},500);
}
};
});
The problem is that i've never used Angular JS in my life and i do'nt have the time to learn it now, maybe after i'm done with the app... and this function is supposed to make it works on mobile, but i don't know how to use it. Could you guys give me a hand and explain me how to insert this code in my project and how to use it? I'm really in need and some help would be very appreciated. by the way, i'm not english native so if you didn't udnerstand something in my post just tell i'll try to say it better ^-^
I hope you will be able to help me, thanks :)
This should be the same in jQuery, but you have to adapt it yourself. You require also the underscore.js library. Hope this helps.
window.setTimeout(function() {
// Find google places div
_.findIndex($(document.querySelectorAll('.pac-container')), function(container) {
// disable ionic data tab
container.setAttribute('data-tap-disabled', 'true');
// leave input field if google-address-entry is selected
container.onclick = function() {
$('#autocomplete').blur();
};
});
},500);
I'm running into an issue where when I run my tests on Jasmine, I get this error below. The problem is, it seems to happen when I try to execute a certain amount of tests. It doesn't seem to be tied to a particular test, as if I comment out some, the tests pass. If I uncomment some tests, the error appears. If I comment out ones that were uncommented before, they all pass again. (ie if I have red, green, blue and orange test and it fails, I comment out orange and blue it passes, then I uncomment blue and orange it fails again, but if I comment out red and green it passes again).
Chrome 41.0.2272 (Mac OS X 10.10.1) ERROR Some of your tests did a
full page reload! Chrome 41.0.2272 (Mac OS X 10.10.1): Executed 16 of
29 (1 FAILED) ERROR (0.108 secs / 0.092 secs)
I'm stumped as to what is going on. The more tests I add, that's when this becomes an issue. Has anyone encountered this before? I have no idea what could be causing it, as nothing in any of my tests do any kind of redirection, and they all pass universally on another persons machine.
In my case the problem was that in my source code I had code directly setting the href on the location object, like window.location.href = 'somewhere';
In my specs I set up a onbeforeunload listener that just returns a string instead of allowing the redirect to take place:
beforeAll(() => {
window.onbeforeunload = () => 'Oh no!';
});
I suppose you are using window.location somewhere in your targeted code. In order to pass it just create a spy for the window.onbeforeunload
Example:
window.onbeforeunload = jasmine.createSpy();
Or even better use $window instead, and this will not happen.
Make sure that your tests are properly isolating all modules under test with mocks/spies. The behavior you are seeing says to me that your tests are not truly running in isolation - they are changing some state somewhere that will trigger a reload.
I recently encountered this error with Karma 0.13.12. I upgraded to Karma 0.13.14 and my tests work again. The problem for me (and probably also for #mqklin) was related to https://github.com/karma-runner/karma/issues/1656 and https://github.com/jasmine/jasmine/issues/945.
There are many ways this error can happen.
If your component has a form element, this might be the cause.
Whenever a button on the form is clicked, this error can happen, even tho your component contains no navigation logic.
What worked for me was upgrading Karma from 1.4.0 to 1.4.1 and changing the maximumSpecCallbackDepth in my jasmine.js file from 20 to 100.
creating a spy on the function which has the window.location / reload fixed the issue for me
Hope you have used window.location = "some url" in your code;
Faced similar problem, and solved by using the below changes.
Replaced window.location in the code with,
window.location.assign("some url");
Do the below in unit test:
spyOn(window.location, "assign").and.callFake(() => {
// Dummy assign call - so that your actual call will be faked and the reload will not happen.
});
You also need to make sure that modules are not being loaded twice. In my case, I had an AngularJS module file -e.g., auth.controller.js which contents were already bundled in a core.js file. Once I excluded the bundled files on karma, the error disappeared.
Try to reduce amount of describe sections or completely remove them. I don't know why, but it works for me.
I was using setTimeout(() => window.location.replace('/'), 10);
I used below code in my unit test and it worked for me.
spyOn(global, 'setTimeout');
In case it was ng-submit callback, which doesn't call "event.preventDefault()" and the browser reloads page. Mocking $location doesn't help in that situation.
According to angularjs documentation you should inject the $window module to be able to solve the testability issue you get. If you really want to do a full page refresh while routing, which will reload the whole application. But anyway...
So for example in component
.controller('ExampleController', ['$scope', '$window', function($scope, $window**)
{
$scope.doRerouteWithPageReload = function() {
return this.$window.location.href = "/myUrl";
};
And then in your test-file you import $window to the test-controller your way, then where you assign spies you can do something like this:
$window = { location: {href: jasmine.createSpy() };
And then the actual test is something like this:
expect($window.location.href).toBe("/myUrl");
Angularjs documentation for reading more about $window.
It will solve this Karma redirect error!
var html = '<script type="text/javascript">';
html += 'window.location = "' + urlToRedirect +'"';
html += '</script>';
$( '.wrapper' ).append( html );
I would like to combine AngularJS and Hoodie, but I am not sure how to do it the correct way.
Let's say I have a basic AngularJS controller
app.controller("c", function($scope) {
$scope.table = [];
$scope.onAdd = function(newEntry) {
$scope.table.push(newEntry);
};
});
After clicking on e.g.
<button ng-click="onAdd('test');">add</button>
Everything works as expected. But now I want to use Hoodie. Currently I am trying this:
app.controller("c", function($scope) {
$scope.table = [];
$scope.onAdd = function(newEntry) {
$scope.table.push(newEntry);
};
hoodie.store.on('entries:add', $scope.onAdd);
});
and anywhere: hoodie.store.add("entries", tmpObject);
The onAdd() gets called and is inserted into the table array (verified in the developer console), but my html table (via ng-repeat="entry in table") is not updated.
First question: Do you know why? What do I think wrong here?
Second question: What would be a good way to combine Hoodie and AngularJS? Would it be better to $watch on the table and insert items into it and store it via Hoodie after getting a change or the other way around and add a new item to the hoodie.store and then on("entries:add") do some Angular stuff?
Thanks in advance!
Heyho =)
First: If you update data-structure via an 'external' event(in this case hoodie), you need to trigger the Digest-Cycle e.g. $rootScope.$apply();
Second: There is a hoodie-angular-plugin that is written by Elmar and me. That solved the most of your basic tasks. That would be the easiest way in this case.
Our Mobile App is getting "TypeError: Attempted to assign to readonly property." only on IOS 8 and the stack traces are not helpful and seem to be in Angular code.
This might be happening because of the "use strict" on top level of Angularjs code.
My questions are (1) why did it start happening only on IOS8? is this an IOS8 bug?
(2) or is this an angular bug surfaced on IOS8? (3) Or maybe we are violating strict mode rules but only IOS8 started to catch them! I am skeptical about the third option because strict mode is supported by other major browsers.
I have found one similar reported issue here.
Looks like this is an IOS8 bug
At least the guys at ember.js will temporarily strip the 'use strict' from their code until it's fixed.
Ember.js issue
SOLUTION -
Note:
angular.copy didn't work for me
lodash cloneDeep didn't work either.
removing "use strict"; didn't help - It just removed the error being logged in a try/catch arround the "erroneous" assignment to a readonly value
For us, the value that was being passed back from the SQL promise value was an array of objects.
The values that we were getting "read only" error on were strings, bools, and numbers.
console.log('this will log');
sqlReturnArray[0].name = "Bob"; // read only error here
console.log('wouldnt get to here to log');
I figured, well, if I can't assign values to properties on THOSE objects within the array, why can't I just copy over all the objects' values? Assignment of objects is by reference so just doing a loop over the array won't help. You need to loop over the keys and values.
This solved our problem
// where sqlReturnArray is the object given from the SQL promise
var newArrayOfObjects = [];
angular.forEach(sqlReturnArray, function (obj) {
var newObj = {};
angular.forEach(obj, function (val, key) {
newObj[key] = val;
});
newArrayOfObjects.push(newObj);
});
I just had this error and the fix was pretty simple.
My Code was-
$http.get('/api/v1/somedata').then(function(result){
$scope.data.somedata = result.data.list;
});
I get the TypeError in the assign. Because I haven't defined $scope.data.somedata anywhere and it got $scope.data undefined and trying to assign some property to it initiated the error.
I simply put $scope.data = {somedata : [] } in the top of the controller. I can also get rid of this error by changing $scope.data.somedata to $scope.somedata because any property of the $scope object that is undefined will end up to the $rootscope and won't give any error. I found this is pretty hard to debug my view-model. And also for this TypeError I can find out what exactly is wrong.
I had it with a form.
my issue was because of binding an SQL Return Object to an input.
after coping with angular.copy() problem resolved.
try to copy your return values and retry.
$scope.yourFunc= function(result) {
var item = angular.copy(result.rows.item(0));
...
};