Javascript Data Model.

javascript

Warning: This is a brain dump. Might not make sense

So what I am thinking of is a datastore

When you update the data locally, it also updates the data via the api in the remote database. Additionally, when the remote database is updated, it updates the local data store.

We keep data in localstorage we keep track of the last update timestamp for data When the user connects initially, the last update timestamp is sent to the server. The server sends through any updates that have occured since that timestamp.

I'll use a basic task list system.

So, say I have a json data structure that is returned from an API Call.

{
    tasks: [
        {
            task_id: 0
            task: 'Buy milk',
            completed: true
        },
        {
            task_id: 1
            task: 'Drink tea',
            completed: false
        },
    ]
}

I want to:

So lets look at the process of adding a new task

On the server side,

I store this in memory, and update this data.

If the data is changed outside of the client, a message is sent that contains the data change. This way the way I am visualising the data in the client will continue to have latest data

I know this is different to something like pouchdb, which communicates directly with a couchdb database. I want to communicate with an api instead.

Thinking about making all API calls a POST to a single endpoint

MODEL

class Tasks {
    function getOne($data){

        // get one task...

        return $result;
    }

    function update($data){

        // do update here...

        syncConnected($result); // send change to the appropriate connected users (not the user that made the request though)
        return $result;  // return the 
    }
}

REQUEST

{
    "resource": "/tasks/1"
    "action": "update",
    "data":{
        "task": "Drink Tea",
        "completed": true
    }
}

RESPONSE

200 {}

WEBSOCKET MESSAGE (Sent to any appropriate connected users, but not the user that made the request)

{
    "resource": "/tasks/1"
    "action": "update",
    "data":{
        "task": "Drink Tea",
        "completed": true
    }
}

much like we call endpoints to update a database via an API, the websocket messages are basically calling endpoints to update the data. The only difference being the endpoints are dumb. There is no logic or processing, they are just updating the data so it is current.

javascript client updates data with the received info

Note, this is a basic merge update. I think I will actually pass the received data to a handler that understands how to merge the received data with the object.

    if (obj.event== "update_model"){
        // MERGE incoming updates with exisiting data
        // This is designed to prevent wiping out data in memory
        let targetObject = ractive.get(obj.keypath);
        mergeObject (targetObject, obj.data);
        ractive.set(obj.keypath, targetObject);
    }

And here's the mergeObject function.


/*
    This function merges two objects together.
*/
function mergeObject (targetObject, obj) {
    Object.keys(obj).forEach(function (key) {

        // delete property if set to undefined or null
        if ( undefined === obj[key] || null === obj[key] ) {
        //   delete targetObject[key]
        }

        // property value is object, so recurse
        else if ( 
        // if ( 
            'object' === typeof obj[key] 
            && !Array.isArray(obj[key]) 
        ) {

            // target property not object, overwrite with empty object
            if ( 
                !('object' === typeof targetObject[key] 
                && !Array.isArray(targetObject[key])) 
            ) {
                targetObject[key] = {}
            }

            // recurse
            mergeObject(targetObject[key], obj[key])
        }

        // set target property to update property
        else {
            targetObject[key] = obj[key]
        }
    })

}

a http call is synchronous ( wait for it to finish before moving on)

Websocket call is asynchronous ( you aren't waiting for the response, and there may or may not be one at some point in the future.)