0

I am calling multiple ajax calls but the code only reaches the API after all the ajax calls are executed.

Javascript:

 function test = function(){
        var entity = {};
        entity.Number = 1;
        appFactory.testPostCall(entity, 'ApiController/TestMethod');

        entity.Number = 2;
        appFactory.testPostCall(entity, 'ApiController/TestMethod');
    }

AppFactory

factory.testPostCall = function (number, appendUrl) {
        var q = $q.defer(); 

        $http({
            method: "POST",
            url: url + appendUrl,
            data: number
        }).success(function (data, status, headers, config) { 
            q.resolve(data);
        }).error(function (data, status, headers, config) {
            q.reject(data); 
        });
        return q.promise;
    }

API

[HttpPost]
        public Nullable<int> TestMethod(TestEntity entity)
        {
            return entity.Number;
        }

I traced how to code runs by breakpoints. calling test() function executes the following:

javascript -> appFactory
javascript -> appFactory
API
API 
//with the parameter Entity having the value Entity.Number = 2 for both API calls.

I tried placing a breakpoint at

entity.Number = 2; 

and wait till the API is called but it seems that the code is waiting for the function to end until the API is called. I am so confused on the behavior of this, I am actually expecting something like the following:

javascript -> appFactory -> API //entity.Number = 1

javascript -> appFactory -> API //entity.Number = 2

Chaining works well but I need to run both independently and I really want to understand whats happening.

    entity.Number = 1;
            appFactory.testPostCall(entity, 'ApiController/TestMethod')
.then(function(data){
            entity.Number = 2;
            appFactory.testPostCall(entity, 'ApiController/TestMethod');
    });

Thank you!!!

John Slegers
  • 45,213
  • 22
  • 199
  • 169

1 Answers1

1

You're passing entity to your function in both guesses. Guess what? In JS, all objects are passed by reference and not by copy. Similar questions are all over SO: Why isn't this object being passed by reference when assigning something else to it?

You have two possibilities to have the behaviour you expect:

  • You can use a closure to make sure that the parameter is passed as you would like
  • You can shallow-copy your object

I would personally go towards a third option, however, which consists in not blindly passing an object to your API.

Community
  • 1
  • 1
Sébastien Renauld
  • 19,203
  • 2
  • 46
  • 66
  • Hey that's one eye opener for me O_O thanks! One less problem for me, the API now receives 1 and 2. Now the only problem is that the API calls are only called after the whole function is executed. – ElementaryStudentProgramming Mar 09 '15 at 11:33
  • @ElementaryStudentProgramming: That is the purpose of a `Promise`. It's non-blocking, async. – Sébastien Renauld Mar 09 '15 at 11:35
  • I'm not quite getting it, if it's "non-blocking", shouldn't the first `appFactory.testPostCall(entity, 'ApiController/TestMethod');` reach the API the moment it is called? What's happening instead is that the code waits for the whole javascript function to be executed before the code reaches the API. – ElementaryStudentProgramming Mar 09 '15 at 11:44
  • @ElementaryStudentProgramming: Nope. If you'd like an analogy, `appFactory.testPostCall` immediately returns, but keeps working on in the background. That's the closest I can get to what actually happens in under 400 characters. If it **didn't** do that, then it'd be blocking. – Sébastien Renauld Mar 09 '15 at 12:11
  • Oh I see, thank you so much! I'm just wondering why it still waits for the whole function to be executed before it runs the API. The behavior on my "GET" calls goes as expected `javascript -> appFactory -> API` . Anyway thank you so much! – ElementaryStudentProgramming Mar 09 '15 at 12:17
  • @ElementaryStudentProgramming: That is beyond the scope of this question. If you like, I can explain it in a bit more detail by email or skype :-) – Sébastien Renauld Mar 09 '15 at 12:24