3

i'am using reflux of reactjs. From Store's action of reflux, i wrote a action to get data from asp.net web api, i think that just only way to get data which use to ajax, someone say with me, i can get data with a plugin jquery but i don't believe it because the $.ajax is best way. I search everything on google but i don't see to resolve for that. If you know something to resolve, please share with me, i really thanks.

Beside, i had a problem with global and local variable of ajax. Please review my code, you can see the bold text which never return a value, the problem which stay with the block of success, the list var isn't update when it outside of the block. What's up problem with that ? how can i fix that error ?

Thank you very much, again!

(function (Reflux, WorkHistoryActions, global) {

    global.workhistoryStore = Reflux.createStore({

        listenables: [WorkHistoryActions],

        init: function () {
            this.storyArr = [];
        },

        getItems: function (resume_id) {
            console.log(resume_id)
            **var list = [];**
            $.ajax({
                type: "get",
                url: global.getHost() + "/api/workhistories/6969607988340821009",
                dataType: 'json',
                crossDomain: true,
                success: function (data) {

                    $.each(data, function (i, v) {
                        **list.push(v);**
                    })

                }
            });
            **return list;**
        },
})
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
Jimmy Mac
  • 37
  • 2
  • 5

2 Answers2

3

I am not sure how to do it in reflux but in a normal flux architecture you would do like so:

    getItems: function (resume_id) {
        $.ajax({
            type: "get",
            url: global.getHost() + "/api/workhistories/6969607988340821009",
            dataType: 'json',
            crossDomain: true,
            success: function(result) {
                workHistoryActionCreator.receiveItems(result);
            },
            error: function(error) {
                workHistoryActionCreator.failToReceiveItems(error);
            }
        });
    }

The store registers to the dispatcher for the actions RECEIVED_WORK_HISTORY_ITEMS and FAILED_TO_RECEIVE_WORK_HISTORY_ITEMS, sets its data and then fires the change event.

Esailija
  • 138,174
  • 23
  • 272
  • 326
  • 6
    @JimmyMac that will pretty much make your application unusable, you will probably not notice anything while developing because responses are instant but in production the entire tab will completely freeze for the duration of the request – Esailija Dec 15 '14 at 16:40
1

JavaScript is an event-driven system where AJAX requests are also Async and the response from the server is received asynchronously.

Using async: false is a bad practice as it will freeze your application and block any parallel execution.

So with async: true (which is default), you can't call a function which makes an AJAX call and returns the response.

Solution #1: Callbacks (old-school)

Modify your getItems function to receive another parameter which is a callback function, when you receive a response from the server, call that callback function and pass list as a parameter to that function call.

Example

getItems: function(resume_id, callback) {

    $.ajax({
        type: "get",
        url: global.getHost() + "/api/workhistories/6969607988340821009",
        dataType: 'json',
        crossDomain: true,
        success: function (data) {

            var list = [];

            $.each(data, function (i, v) {
                list.push(v);
            })

            callback(list);

        }
    });

    // Return nothing

}

How to use?

getItem(resume_id, function(list){

});

Solution #2: JavaScript Promises (recommended)

Return a JavaScript promise and set the callback using then() function. I use kriskowal's promise implementation

Example

getItems: function (resume_id) {

    var deferred = Q.defer();

    $.ajax({
        type: "get",
        url: global.getHost() + "/api/workhistories/6969607988340821009",
        dataType: 'json',
        crossDomain: true,
        success: function (data) {

            var list = [];

            $.each(data, function (i, v) {
                list.push(v);
            });

            deferred.resolve(list);


        }
    });

    return deferred.promise;

}

How to use?

getItem(resume_id).then(function(list){
    // use list
});
Sanket Sahu
  • 8,468
  • 10
  • 51
  • 65
  • i really thanks Sanket, that resolve is a good idea, i will try it. the problem is block of success func (1) and outside of ajax (2). For async = true, for priority, (2) is first, (1) is second. And result is return null data. – Jimmy Mac Dec 16 '14 at 13:58
  • Thnaks! JavaScript is totally different when it comes to talking to a third party system. Everything is done through callbacks / promises. When you move to Node.js and Mongo, even DB statements work in async. – Sanket Sahu Dec 16 '14 at 14:07
  • i see nodejs which is difficult to approach, my company recently transfer to Nodejs and Mongo to Reactjs and .NET API and Mongo, i feel lucky ^_^, even that i feel difficult with config reflux of reactjs because it related to requirejs, i retrieved everything on docs of requirejs but nothing steps by steps. What do you think of reactjs and angular ?. – Jimmy Mac Dec 16 '14 at 14:41
  • I am writing a blog post at Toptal which will be published this week. The title says, "Why did I switch from AngularJS to React". I will share the link here. – Sanket Sahu Dec 16 '14 at 14:45
  • that's great, i'll read your post, share with me when you finish, here my email is "phuochuy.hcmup@gmail.com". *_*. – Jimmy Mac Dec 16 '14 at 14:50