Ionic +LokiJS всегда создает "ionic.bundle.js:26794 TypeError: Невозможно прочитать свойство" insert "из неопределенного"

После всех моих проблем с SQLite я хотел использовать другое решение для моего приложения Ionic. LokiJS часто упоминали, поэтому я попробовал. Но и с LokiJS мне не повезло.

На данный момент у меня есть очень простой код, который должен работать без проблем:

.controller('ProjectsController', ['$scope', '$state', '$ionicPlatform', function($scope, $state, $ionicPlatform) {
  var pcVm = this;

  var db;
  var projects1;

  $ionicPlatform.ready(function(){

    var idbAdapter = new LokiIndexedAdapter('loki');
    db = new loki('lkr-v4', {
      autoload: true,
      autoloadCallback : getAllProjects,
      autosave: true,
      autosaveInterval: 10000,
      adapter: idbAdapter
    });

    function getAllProjects() {
      var options = {};
      db.loadDatabase(options, function() {
        projects1 = db.getCollection('projects'); // GET
        if (!projects1) {
          projects1 = db.addCollection('projects'); // ADD
        }
        console.log('Databaseinformation');
        console.log(db);
        console.log('Collectioninformation');
        console.log(projects1);
      });
    }

    console.log('Insert something');
    projects1.insert({ name : 'odin' });
  }); // End of .ready()

Но я всегда получаю сообщение:

ionic.bundle.js:26794 TypeError: Cannot read property 'insert' of undefined
    at controllers.js:309
    at ionic.bundle.js:56230
    at Object.ready (ionic.bundle.js:2140)
    at Object.ready (ionic.bundle.js:56223)
    at new <anonymous> (controllers.js:283)
    at Object.instantiate (ionic.bundle.js:18010)
    at $controller (ionic.bundle.js:23412)
    at self.appendViewElement (ionic.bundle.js:59900)
    at Object.render (ionic.bundle.js:57893)
    at Object.init (ionic.bundle.js:57813)(anonymous function) @ ionic.bundle.js:26794(anonymous function) @ ionic.bundle.js:23507$broadcast @ ionic.bundle.js:30720$state.transition.resolved.then.$state.transition @ ionic.bundle.js:52157processQueue @ ionic.bundle.js:29127(anonymous function) @ ionic.bundle.js:29143$eval @ ionic.bundle.js:30395$digest @ ionic.bundle.js:30211$apply @ ionic.bundle.js:30503done @ ionic.bundle.js:24824completeRequest @ ionic.bundle.js:25022requestLoaded @ ionic.bundle.js:24963
controllers.js:301 Databaseinformation

Пожалуйста помоги. Может быть, у меня та же проблема с SQLite и LokiJS? Но я не могу найти проблему...

Спасибо, Кристиан.


ОБНОВЛЕНИЕ - 2016-08-05

Итак, я снова часами часами искал, пытался и всегда получал одни и те же ошибки. Мне интересно, почему все учебные пособия выглядят одинаково и работают, но для меня невозможно запустить его.

Я полностью переписал свой завод:

(function() {
  'use strict';

  angular.module('lkr-v4')

    .factory('PersistenceService', ['$q', 'Loki', PersistenceService]);

      function PersistenceService($q, Loki) {
        // Needed variables
        var lkrDb; // Database
        var projects; // Collection of JSON strings

        // Accessible Members Up Top
        // https://github.com/johnpapa/angular-styleguide/tree/master/a1#style-y052
        var pService = {
          initDB: initDB,
          getAllProjects: getAllProjects,
          addProject: addProject,
          updateProject: updateProject,
          deleteProject: deleteProject
        };
        return pService;

        // Initialization of the database
        function initDB() {
          var idbAdapter = new LokiIndexedAdapter('loki');
          lkrDb = new loki('lkr-v4', {
            autoload: true,
            autoloadCallback: getAllProjects,
            autosave: true,
            autosaveInterval: 10000,
            adapter: idbAdapter
          });
        }

        // Function to return a collection of JSON strings (all found projects) in the LokiJS database file
        function getAllProjects() {
          // What is $q? See https://docs.angularjs.org/api/ng/service/$q
          return $q(function (resolve, reject) {
            var options = {};
            lkrDb.loadDatabase(options, function () {
              projects = lkrDb.getCollection('projects'); // GET!
              // If the database file is empty
              if (!projects) {
                projects = lkrDb.addCollection('projects'); // ADD!
              }
              resolve(projects.data);
            });
          });
        }

        // Function to add a project
        function addProject(project) {
          if(lkrDebug) {
            console.log('Inside of addProject from the factory');
            console.log('This is the projects object');
            console.log(this.projects);
            console.log('This is the given value of the new project');
            console.log(project);
          }
          projects.insert(project);
        }

        // Function to update a project
        function updateProject(project) {
          projects.update(project);
        }

        // Function to delete a project
        function deleteProject(project) {
          projects.remove(project);
        }

      } // End of function PersistenceService

})(); // End of IIFE

Я вызываю PersistenceService.initDB() в run() моего app.js. ЭТО РАБОТАЕТ!

Все мои страницы (4) имеют свой собственный контроллер, используемый как контроллер. В контроллере моей первой страницы я попробовал этот код:

  // Test #1: Get data
  PersistenceService.getAllProjects().then(function(projects) {
    pcVm.projects = projects;
    if(lkrDebug) {
      console.log('Inside of getAllProjects().then() from the controller');
      console.log('This is the project object from the PersistenceService');
      console.log(projects);
      console.log('And this ist the pcVm.projects object from the controller');
      console.log(pcVm.projects);
    }
  });

ОНО РАБОТАЕТ! Я вижу правильную информацию в консло, и не получаю никакой ошибки.

Следующий код размещается непосредственно после кода выше в том же контроллере:

  // Test #2: Add a project
  PersistenceService.addProject({ name : 'odin' });

И это выдает следующие строки (и ошибки) на консоли

Inside of addProject from the factory
persistence.services.js:65 This is the projects object
persistence.services.js:66 undefined
persistence.services.js:67 This is the given value of the new project
persistence.services.js:68 Object {name: "odin"}
ionic.bundle.js:26794 TypeError: Cannot read property 'insert' of undefined
    at Object.addProject (persistence.services.js:70)
    at new ProjectsController (projects.controller.js:31)
    at Object.instantiate (ionic.bundle.js:18010)
    at $controller (ionic.bundle.js:23412)
    at self.appendViewElement (ionic.bundle.js:59900)
    at Object.render (ionic.bundle.js:57893)
    at Object.init (ionic.bundle.js:57813)
    at self.render (ionic.bundle.js:59759)
    at self.register (ionic.bundle.js:59717)
    at updateView (ionic.bundle.js:65398)(anonymous function) @ ionic.bundle.js:26794(anonymous function) @ ionic.bundle.js:23507$broadcast @ ionic.bundle.js:30720$state.transition.resolved.then.$state.transition @ ionic.bundle.js:52157processQueue @ ionic.bundle.js:29127(anonymous function) @ ionic.bundle.js:29143$eval @ ionic.bundle.js:30395$digest @ ionic.bundle.js:30211$apply @ ionic.bundle.js:30503done @ ionic.bundle.js:24824completeRequest @ ionic.bundle.js:25022requestLoaded @ ionic.bundle.js:24963
projects.controller.js:22 Inside of getAllProjects().then() from the controller
projects.controller.js:23 This is the project object from the PersistenceService
projects.controller.js:24 [Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object]
projects.controller.js:25 And this ist the pcVm.projects object from the controller
projects.controller.js:26 [Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object]

Это немного странно, потому что для меня это выглядит как addProject() называется bevore getAllProjects()?

Поэтому я добавил строку console.log(lkrDb); в addProject-функции, чтобы увидеть, загружена ли база данных, и я сделал еще несколько тестов. Оказалось, что initDB в app.js работает, и что addProject-функция также может работать с открытой базой данных.

Мой вывод таков: я что-то не так делаю в контроллере или с помощью функции getAllProjects!?

Я буду продолжать поиск, но я был бы очень благодарен за любой намек...

Спасибо, Кристиан.

2 ответа

Решение

Теперь я понимаю вещь обещаний! Это мне очень помогло: http://andyshora.com/promises-angularjs-explained-as-cartoon.html

Но даже если это то, о чем я должен по-настоящему заботиться, это не проблема. Проблема основана на уроках, которые я использовал. Я не знаю почему и как, но учебники работают, а мое приложение не просто потому, что: пока я не вызываю функцию getAllProjects(), переменная projects1 не имеет данных. AutoloadCallback не вызывает функцию автоматически!? Я открыл проблему в проекте LokiJS, чтобы спросить, что я делаю неправильно, или, если это не идея autoloadCallback.

Когда у меня будет готовое рабочее решение, я опубликую его здесь...

projects1 не инициализирован должным образом, вы должны позвонить projects1.insert() только после db.loadDatabase()callback

Это должно работать. Это просто всплеск, попробуйте использовать factory для операций с базой данных. И пройдите область видимости переменной javascript, чтобы вы больше не сталкивались с этой проблемой.

db.loadDatabase(options, function() {
  projects1 = db.getCollection('projects');
  if (!projects1) {
    projects1 = db.addCollection('projects');
  }
  projects1.insert({name: 'odin'});      

  });

Надеюсь, это поможет, Happy Coding:)

Обновление: пожалуйста, обновите вопрос вашей актуальной проблемой.

Другие вопросы по тегам