models/storage.js

/**
 * @module app/models/storage
 * @requires jquery
 * @requires knockout
 * @requires common
 * @requires settings
 * @requires ko-mapping
 * @requires ko-postbox
 */
define(
    [
        'jquery',
        'knockout',
        'common',
        'settings',
        'ko-mapping',
        'ko-postbox'
    ],
    function($, ko, lib, settings, mapping) {
        var interval = setInterval(function() {
            if (typeof $.competency === 'object') {
                $.storage = new Storage();
                console.log('Storage initialized');
                clearInterval(interval);
            }
        }, 30);

        function toggle(bool) {
            return bool === undefined ? true : !bool;
        }

        /**
         * STRIP UNRELATED PROPS
         * Makes the data server friendly, before sending the ajax request.
         * @param  {object} doc pouchdb document
         * @return {object} doc.data
         */
        function stripUnrelatedProps(doc) {
            return JSON.parse(ko.toJSON(doc.data));
        }

        /**
         * This is a wrapper for the competencydb methods, responsible for offline saving
         * @construct
         * @alias module:app/models/storage
         */
        function Storage() {
            var self = this;
            var VIEW_NAMES = {
                BY_UUID: 'ft_byUuid'
            };
            this.online = ko.observable().subscribeTo('aegis.online', true);

            /**
             * SAVE
             * Saves on localdb or to the server (if online)
             * @param  {object | array} data the data to be saved
             * @return {object | array}      
             */
            this.save = function save(doc, callback) {
                    console.log('Storage.save: Passed doc ', doc);
                    doc.synced = false;

                    this.getByUuid(doc.data.uuid).then(function(result) {
                        if (result.rows && !result.rows.length) {
                            // ----------------
                            // NEW RECORD
                            // ----------------
                            doc.uuid = lib.createUuid();
                            if (!doc.data.uuid) {
                                doc.data.uuid = lib.createUuid();
                            }
                        } else {
                            // ----------------
                            // EXISTING RECORD
                            // ----------------
                            var existing_doc = result.rows[0].doc;
                            doc._id = existing_doc._id;
                            doc._rev = existing_doc._rev;
                        }
                        var saveByTypeAndId = $.competency.saveByTypeAndId(doc);
                        saveByTypeAndId.then(function(saved_doc) {
                            if (self.online()) {
                                var data = stripUnrelatedProps(doc);
                                // --------------------
                                // then save to server
                                // --------------------
                                var AJAX_POST = $.ajax({
                                    type: 'POST',
                                    url: settings.formEditorURL,
                                    data: data
                                });

                                // ---------------------------
                                // 
                                // ----------------------------
                                AJAX_POST.done(function(response, textStatus, jqXHR) {

                                    if (jqXHR.status >= 200) {

                                        var getById = $.competency.getById(saved_doc.id);

                                        getById.then(function(doc) {

                                            if (callback) {
                                                // ----------------------------------------------------
                                                // then execute it
                                                // (For now, callback is used mostly for redirection)
                                                // ----------------------------------------------------
                                                callback(doc.data.uuid);
                                            }
                                            // --------------------
                                            // add the synced flag
                                            // --------------------
                                            doc.synced = true;
                                            if (doc.type === 'template') {
                                                // -----------------------
                                                // update the template id
                                                // -----------------------
                                                doc.data.id = response.id;
                                                doc.data.name = response.name;
                                                doc.data.description = response.description;
                                                doc.data.fields = response.fields;
                                                doc.data.visit_type = response.visit_type;
                                            }
                                            // ---------------------------------
                                            // then, update the local db record
                                            // ---------------------------------
                                            $.competency.saveByTypeAndId(doc)
                                                .then(function(updated_doc) {});
                                        });

                                        getById.catch(function(err) {
                                            console.error('Storage.save: $.competency.getById error ', err);
                                        });
                                    } //END: if
                                });

                                AJAX_POST.fail(function(err) {
                                    console.error('Storage.save: ajax post error', err);
                                });
                            } // END: if
                        });
                    });
                    return
                    // -------------------------------
                    // Save to local db
                    // -------------------------------
                    var saveByTypeAndId = $.competency.saveByTypeAndId(doc);

                    saveByTypeAndId.then(function(savedDoc) {


                    });

                    saveByTypeAndId.catch(function(err) {
                        console.error('Storage.save: $.competency.save error', err);
                    });
                } //END: Storage.save

            /**
             * GET BY UUID
             * Get by template uuid
             * @param  {string}   uuid     
             * @param  {Function} callback 
             * @return {Promise}            
             */
            this.getByUuid = function(uuid, callback) {
                var _args = [].slice.call(arguments, 0);
                var uuid = _args.shift();
                var callback = false;
                var include_docs = true;
                if (_args.length > 1) {
                    callback = _args[0];
                    include_docs = _args[1];
                } else {
                    switch (typeof _args[0]) {
                        case 'function':
                            callback = _args[0];
                            include_docs = true;
                            break;

                        case 'boolean':
                            callback = false;
                            include_docs = _args[0];
                            break;
                        default:
                    }
                }
                console.log('Storage.getByUuid ', uuid);
                return $.competency.theDB.query(VIEW_NAMES.BY_UUID, {
                        key: uuid,
                        include_docs: true
                    })
                    .then(function(result) {
                        if (callback) {
                            if (result.rows.length) {
                                var record = result.rows.pop();
                                // -------------------------
                                // Remove the _rev and _id
                                // -------------------------
                                callback && callback(stripUnrelatedProps(record.doc));
                            } else {
                                var url_params = ['/', uuid, '/edit'].join('');
                                $.ajax({
                                    url: settings.formEditorURL + url_params
                                }).done(function(response) {
                                    callback && callback(response);
                                });
                            }
                        }
                        return result;
                    })
                    .catch(function(err) {
                        console.log('Storage.getByUuid: ', err);
                    });
            };

        }
    });