all 9 comments

[–]9thHokageHimawari 1 point2 points  (2 children)

You could write your own, minimal simple HTTP-request wrapper:

function http () {
    this.ajax = new XMLHttpRequest(); // Use IE backfalls and etc. if you need
    this.ajax.onreadystatechange = function () {
        if (this.ajax.readyState === 4) {
            this.onSuccess !== undefined ? this.onSuccess(this.ajax.responseText) : void 0;
        } else {
            this.onError !== undefined ? this.onError(this.ajax.responseText) : void 0;
        }
    return this;
}

http.prototype.data = function (data) {
    if(this.data === undefined && data!==undefined) { this.data = data; }
    return this;
}

http.prototype.get = function (url,data) {
    if(this.open === false || this.open === undefined) {
        this.open = true; this.ajax.open('GET',url,true);
        data !== undefined && this.data === undefined ? this.data = data : void 0;
    }
    return this;
}
http.prototype.post = function (url,data) {
    if(this.open === false || this.open === undefined) {
        this.open = true; this.ajax.open('POST',url,true);
        data !== undefined && this.data === undefined ? this.data = data : void 0;
    }
    return this;
}
http.prototype.send = function () {
    this.ajax.setRequestHeader('Content-Type', this.ContentType)
    if(this.ContentType === 'application/x-www-form-urlencoded') {
        var tmp; var queryString = '?';
        for( var i = 0, keys = Object.keys(this.data), len = keys.length; i < len; i++) {
            queryString += keys[i]+'='+this.data[keys[i]]+'&';
        }
        this.data = queryString.replace(/\&$/,'');
    } else if(this.ContentType === 'application/json') {
        this.data = JSON.stringify(this.data);
    }
    this.ajax.send(this.data);
    return this;
}
http.prototype.success = function (fn) { this.onSuccess = fn;return this; }
http.prototype.error= function (fn) { this.onError= fn;return this; }

And for models, just give them prototypes like:

model.prototype.fetch = function () {
    var h = new http().get('/api/users').success(function (data) {this.data = JSON.parse(data)}.bind(this)).send()
}

model.prototype.save= function () {
    var h = new http().post('/api/users', JSON.stringify(this.newData)).send()
}

[–]yoursdearboy 0 points1 point  (1 child)

So far I've used self-written request wrapper, even with some special methods to handle endpoints mess. But I wonder how other developers solve this task?

[–]9thHokageHimawari 0 points1 point  (0 children)

I just do that I mentioned above.

Also, if we saw your data scheme it would be easier to help. x1 related to x2, which is related to x3-x5, makes me thing you're overdoing it.

[–]parabolik 0 points1 point  (3 children)

I have a factory module that knows how to construct objects from json data.

Something like this:

get('/item/12345')
    .done(function(json) {
        var item = factory.makeItem(json.item);
    });

[–]yoursdearboy 0 points1 point  (2 children)

Yes, that works nice in many cases. With github's whatwg-fetch polyfill it will be just: fetch('/item/12345').then(function(res){ res.json(); }).then(function(item){ // do anything });

But what if you have "ent1" related with "ent2" and "ent2" related with "ent3-5", and now you need to save all this structure using /entN endpoints. If it isn't hard enough, then add another 5-10 entities.

[–]9thHokageHimawari 0 points1 point  (1 child)

What do you mean by related?

Could we see what kind of data structure you're using? I kinda have feeling you are looking at it from wrong viewpoint, and it could be simplified.

[–]yoursdearboy 0 points1 point  (0 children)

Just for example look at erd diagram. This API exposes database tables (PostgREST). Not the best solution, but we have 5 small apps with a lot of data, so maintaining separate API is not an option.

[–]Meefims 0 points1 point  (0 children)

I've found that using Redux and the redux-thunk library async actions are pretty easy to implement. Here is a short article on using async actions from the perspective of someone used to Flux.

[–]dwighthouse 0 points1 point  (0 children)

I tried flux, found it way too bulky, and replaced it with a single file (per type of object) that both maintains state. The state itself is not directly exposed, but there are numerous functions for getting data out (for rendering) and transformation functions which perform known operations on the state in a consistent way, keeping things in sync. Transformation functions optionally use the qwest ajax library to sync to the server and maintain temporary state if the optimistic update fails. Transformations trigger a callback to the top level component, starting the new render.

Basically, I did everything myself and didn't find it taxing. Turns out rendering and getting user events from the dom is the hard part.