Localstorage on iOS build don't works the first time the app start


#1

Hi guys, when I build my iOS app and run it in iOS Simulator or directly in my iPhone, ONLY the first bootstrap I can’t write/read any objects inside my localstorage. If I force stopping the app and re-run it, all works fine… :frowning:

I use localStorageService.

In .run method inside $ionicPlatformReady, I check if localstorage object exists and I create new one (empty array) if it return null or undefined:

if (localStorageService.get('territories') === null || typeof localStorageService.get('territories') == 'undefined') {
      localStorageService.set('territories',[]);
  }

then, in my factory:

.factory('Territories', function(localStorageService) {

var territories = localStorageService.get("territories");

return {
    all: function() {
        return territories;
    },
    set: function(territory){
        territories.push(territory);
        return localStorageService.set("territories",territories);
    },
    remove: function(territory) {
        territories.splice(territories.indexOf(territory), 1);
        return localStorageService.set("territories",territories);
    },
    update: function(updatedTerritory){
        for (var i = 0; i < territories.length; i++) {
            if (territories[i].id === updatedTerritory.id) {
                territories[i].name = updatedTerritory.name;
                localStorageService.set("territories", territories);
            }
        }
        return null;
    },
    get: function(terrId) {
        for (var i = 0; i < territories.length; i++) {
            if (territories[i].id === terrId) {
                return territories[i];
            }
        }
        return null;
    }
};

})

and in my controller:

.controller('notesCtrl', function($scope, $ionicPopup, Territories, Visits, Owners, Addresses, $ionicListDelegate, $cordovaDialogs, $ionicPlatform) {

$scope.territories = Territories.all();

$scope.addTerritory = function(){

    $ionicPlatform.ready(function() {$cordovaDialogs.prompt('Inserisci il nome e il numero di territorio', 'Nuovo territorio', ['Annulla','Crea'], '')
        .then(function(result) {
            var input = result.input1;
            var btnIndex = result.buttonIndex;
            if (btnIndex == 0){
                return;
            }else{

                $scope.$watch('territories', function(){
                    var territory = {
                        "id": Math.random().toString(36).substr(2, 9),
                        "name":input
                    };
                    Territories.set(territory);
                    $scope.territories = Territories.all();
                })
            }
        });
    });
};

All works fine in browsers, Safari included, and in Ionic View. But, as I mentioned above, in the simulator it works only from the second bootastrap. It seems that the app don’t loads LocalStorage at the first start.

Help me please :’-(


#2

Hi.

Short quick answer and not sure whether this has a direct impact, but I’d recommend using array notation for injection because of potential minification issues: https://docs.angularjs.org/guide/di#dependency-annotation

Second: Why not just use window.localStorage and wrap it like this - works for me at least: http://learn.ionicframework.com/formulas/localstorage/#angularjs-service

Greetings


#3

Hi @seppsepp, I tried to use array notation instead but it is still not working.
About window.localStorage I prefer first to be sure that the logic is correct because everything works fine in browser and from second application bootstrap…


#4

Ok, I tried to wrapp window.localStorage and the result is the same…it works only from the second bootstrap.


#5

What exactly then is the symptom?


#6

As you can see in the code, I checked if “territories” object exists. If not, I created a new empty array. Then, when I click on the add button, $scope.addTerritory function is called and it is inserted a new object inside territories array. Everything works on browsers and inside Ionic View. But when I deploy into iOS and run the code on iOS Simulator, the empty array is missing (null, undefined?) and I can’t create new object inside it. The strange thing is that if I close forcedly and relaunch the app a second time everything works. Why iOS doesn’t immediately create an empty array if territories doesn’t exist while browser does?? :frowning:
Is it right to put this control inside .run method?


#7

I don’t get it neither. Could you put a minimal (failing :wink: ) example on some service like http://plnkr.co?


#8

It doesn’t works on plnkr and co. because there is native functionalities and the problem exist only in IOS simulator/device. Everything works in browsers…


#9

I solved! I removed localstorage check within .run method and in factory I wrote:

.factory('Territories', ['localStorageService', function($localstorage) {



var territories = $localstorage.get("territories") || [];


return {
    all: function() {
        return territories;
    },
    set: function(territory){
        territories.push(territory);
        if ($localstorage.get("territories")){
            return $localstorage.set("territories",territories);
        }else{
            return $localstorage.set("territories",[territories]);
        }

    },
    remove: function(territory) {
        territories.splice(territories.indexOf(territory), 1);
        return $localstorage.set("territories",territories);
    },
    update: function(updatedTerritory){
        for (var i = 0; i < territories.length; i++) {
            if (territories[i].id === updatedTerritory.id) {
                territories[i].name = updatedTerritory.name;
                $localstorage.set("territories", territories);
            }
        }
        return null;
    },
    get: function(terrId) {
        for (var i = 0; i < territories.length; i++) {
            if (territories[i].id === terrId) {
                return territories[i];
            }
        }
        return null;
    }
};

}])

the localstorage chek now is inside factory service. In localstorage object exists I can write inside it, else I create a new empty array with the object created inside it.

Thanks!