1

As first question here, there is something i've been stuck for quite some time, despite me searching on numerous forums. I'm sorry if my english is not perfect, I hope I'm clear enough for you to be able to understand me and help me get through this.

I'm trying to learn some mobile development with Cordova. I choose to use AngularJS to have a better application management, but I can't make is work as I want.

I want to create an application instagram-like, in which memories will be stored. The application uses two pages :

  • a page displaying all stored memories ;
  • a page adding a memory. Memories are stored in a local json file.

Here is my code (for now) :

note : my code has been translated in english for a better comprehension. I hope I didn"t make any translation error, unrelated to the topic at hand

index.html

<!DOCTYPE html>
<html ng-app="myMemories">
<head>
    <title>My memories</title>

    <!-- Cordova references -->
    <script src="cordova.js"></script>
    <script src="scripts/platformOverrides.js"></script>

    <!-- Downloaded files -->
    <script src="scripts/jquery-2.1.4.js"></script>
    <script src="scripts/angular.js"></script>
    <script src="scripts/angular-route.js"></script>

    <!--Personal files-->
    <script src="lib/index.js"></script>
    <script src="lib/app.js"></script>
    <script src="lib/controllers/addMemory.js"></script>
    <script src="lib/controllers/displayMemories.js"></script>
</head>
<body>
    <div class="container">
        <!-- Menu -->
        <nav class="navbar navbar-inverse navbar-fixed-top">
            <ul class="nav navbar-nav">
                <li class="pull-left"><a href="#/">All</a></li>
                <li class="pull-right"><a href="#/addMemory">Add</a></li>
            </ul>
        </nav>
        <!-- Content -->
        <div>
            <ng-view></ng-view>
        </div>
    </div>
</body>
</html>

index.js (first loaded file, auto-generated)

(function () {
    "use strict";

    document.addEventListener( 'deviceready', onDeviceReady.bind( this ), false );

    function onDeviceReady() 
        document.addEventListener( 'pause', onPause.bind( this ), false );
        document.addEventListener( 'resume', onResume.bind( this ), false );

        //angular.bootstrap(document, ['myMemories']); //aborted try
    };

    function onPause() {
    };

    function onResume() {
    };
} )();

app.js (second loaded file, creating the application)

var app = angular.module('mesSouvenirs', ['ngRoute']);

app.config(function ($routeProvider) {
    $routeProvider
        .when("/", {
            templateUrl: "vues/souvenirs.html",
            controller: "souvenirsControleur"
        })
        .when("/ajouteSouvenir", {
            templateUrl: "vues/ajouterSouvenir.html",
            controller: "ajouterSouvenirControleur"
        })
        .otherwise({ redirectTo: "/" });

});

addMemory.html (view to add a memory)

<form role="form" class="col-xs-12">
    <div class="form-group">
        <label for="titre">Title :</label>
        <input type="text" id="titre" class="form-control" ng-model="souvenir.titre" placeholder="Add a memory title" />
    </div>
    <div class="form-group">
        <label for="image">Image :</label>
        <button id="image" class="form-control btn btn-default">Add...</button>
    </div>
    <button class="btn btn-default" ng-click="creatingMemory()">Create</button>
</form>

addMemoryController.js (add a memory. For now, a memory is a static json stored in a local file. Dynamic control will mbe added later on)

app.controller("addMemoryController", function ($scope,$location) {
    //Array of stored memories
    $scope.memoriesList = [];

    //Souvenir courant à ajouter
    $scope.memory= {
        image: "image/mountain.png",
        title:""
    }

    $scope.creatingMemory= function () {
        $scope.memoriesList .push($scope.souvenir);
        $scope.saveArray();
    }

    $scope.saveArray= function () {
        window.requestFileSystem(window.PERSISTENT, 0, $scope.fileSystemReceived, $scope.errorHandler);
        $location.path("/");
    }

    $scope.fileSystemReceived = function (fileSystem) {
        fileSystem.root.getFile("souvenirs.json", { create: true, exclusive: false }, $scope.fileEntryReceived, $scope.errorHandler);
    }

    $scope.fileEntryReceived = function (fileEntry) {
        fileEntry.createWriter($scope.fileWriterReceived, errorHandler);
    }

    $scope.fileWriterReceived = function (fileWriter) {
        var listeSouvenirsText = angular.toJson($scope.listeSouvenirs);
        fileWriter.write(listeSouvenirsText);
    }

    $scope.errorHandler = function (error) {
        console.log(error);
    }
});

Here is my problem : when I click on the "Create" button, I get this JS error : TypeError: window.requestFileSystem is not a function at Scope.$scope.savingArray in (http://localhost:4400/lib/controleurs/addMemoryController.js:19:16)

I even tried to encapsulate the definition using angular.bootstrap(), but I then get this error :

Uncaught Error: [ng:btstrpd] App Already Bootstrapped with this Element 'document'

Could someone tell me what I did wrong ?

5
  • 1
    One thing you can try is injecting the $window service to your controller and replacing all instances of window for $window. It is an Angular wrapper around the window object so it can keep track of window events. Commented Dec 28, 2015 at 21:16
  • You need the cordova-plugin-file in order to access local file system of your mobile device. Commented Dec 29, 2015 at 9:30
  • Hi. @DavidMeza : I tried to replace elements with $window, but I get the same error : "$window.requestFileSystem is not a function" Commented Dec 29, 2015 at 19:04
  • @beaver : I also had this message when adding the cordova-plugin-file : If this is an update to an existing application that did not specify an "AndroidPersistentFileLocation" you may need to add: "<preference name="AndroidPersistentFileLocation" value="Compatibility" />" to config.xml in order for the application to find previously stored files. Commented Dec 29, 2015 at 19:11
  • See github.com/apache/… for details Commented Dec 29, 2015 at 20:11

1 Answer 1

1

Alright.

So I found something which seems to resolve that issue. In fact, the poblem wasn't really with the window.requestFileSystem function, but with the browser and app authorizations.

First of all, I have to reset the requestFileSystem depending on the browser used :

window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;

Then, I have to request a file Quota. I thought that putting a "0" meant "I don't have any max quota", but this is deprecated. Here is what I had to do :

var requestedBytes = 1024*1024*10; // 10MB
navigator.webkitPersistentStorage.requestQuota (
    requestedBytes,
    function (grantedBytes) {
        window.requestFileSystem(PERSISTENT, grantedBytes, $scope.fileSystemReceived, $scope.errorHandler);
    },
    $scope.errorHandler
);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.