1

I have two function with which I am handling the store and remove data by calling service end points. Below mentioned code will first check whether the data with the key mentioned is available or not.

RemoteDataStore.prototype.get = function(key,cb){
    $.get(this.serverUrl + "?emailAddress=" + key ,function(serverResponse){
        console.log(serverResponse);
        cb(serverResponse);
    });
};

And in the below mentioned code, I want to check whether the specified key is available or not. Based on that I will invoke the service end point to delete that specific data.

RemoteDataStore.prototype.remove = function(key){
    this.get(key,function(serverResponse){
        _id = serverResponse[0]["id"];
    });

    console.log("The id to remove is :" + _id);
    /*$.ajax(this.serverUrl + "/" + key ,{
        type: "DELETE"
    });*/
};

The way I passed the parameters to the get function is not working. With this code,serverResponse is not available in remove function. serverResponse is the array of JSON objects returned by the service. What's the possible way to access the serverResponse variable inside remove function without changing get function?

Bucket
  • 7,415
  • 9
  • 35
  • 45
Swapnil
  • 801
  • 3
  • 19
  • 42
  • 1
    You were so close... But `_id` is not set until the callback is run, so if you want to use it, **do so in the callback**. – Niet the Dark Absol Mar 09 '18 at 16:49
  • Return `severResponse` – zer00ne Mar 09 '18 at 16:49
  • Looks to me that you're using callbacks but then forgetting the reason we need them. You're assigning to an outer `_id` variable inside the callback, but then expecting the value to be available outside the callback. If that was possible, there would be no need for callbacks in the first place. Use the `_id` where it's available. –  Mar 09 '18 at 16:49
  • @doodlemeister: I completely agree with your points. I am new to the jQuery concepts, so not sure about the proper way to do this. The _id variable is the local variable in remove function. I just want to access a id field which is there in serverResponse. – Swapnil Mar 09 '18 at 17:07
  • @zer00ne : Do you mean to say like this var _id = this.get(key,function(serverResponse){ return serverResponse[0]["id"]; }); – Swapnil Mar 09 '18 at 17:08
  • More like `var newArray = serverResponse.map(function(eleVal, arrIdx){ ..`.From the iterations of the array `serverResponse` return the results as a new array (let's call it `newArray`) `map()` is guaranteed to return a new array. Normally we don't need to return on callbacks because dealing with client viceversa server is asynchronous, but if for some reason you find yourself in a synchronous situation, a return from a callback could be useful for monitoring. – zer00ne Mar 09 '18 at 17:31
  • @zer00ne : Yeah, but the problem is serverResponse is undefined inside remove function. And I am not allowed to make changes in the get function. Is there any way, I can get the serverResponse in remove function? – Swapnil Mar 09 '18 at 17:37
  • @Swapnil: The simple answer is that you can't. I understand your natural inclination is to think that there's a way for the code to "block" until that variable has been populated, but there really isn't. That's the nature of asynchronous code. Your flow of execution needs to continue from the point inside the function where the data is actually available. –  Mar 09 '18 at 17:44
  • @zer00ne: `$.get` is always async, so `this.get` will always be async, so there's no return value that will be able to return the data being fetched. –  Mar 09 '18 at 17:46
  • Yeah which is why I suggested `.map()` but I don't see where this would be going anyhow... – zer00ne Mar 09 '18 at 17:48
  • Using cb(serverResponse) in get function, can I get the value in remove function as the get expects some anonymous function. – Swapnil Mar 09 '18 at 17:58
  • @zer00ne: What will map do? It's just as reliant on synchronous code as a return statement. –  Mar 09 '18 at 18:07
  • @Swapnil: You already have the value in the `remove` function. If you can alter that function, then you can add a parameter to receive a callback just like in `get`. So `...remove = function(key, cb) {` and then `cb(serverResponse[0]["id"]);` in place of your `_id = ` assignment. –  Mar 09 '18 at 18:09
  • @doodlemeister: Your solution looks perfect. The problem is remove is called by the method defined in another module which again developed by someone else and I can't change it. the remove function acts as a interface to that another method. I am ready for any sort of solution with the restriction that I can not change the way functions (get and remove) are defined. I can change the remove function definition only. Is there any way? – Swapnil Mar 09 '18 at 18:23
  • I am stuck at the way how to access the data fetched by get method inside remove function. Just the restriction is not to change the get function as well as remove function declaration. – Swapnil Mar 09 '18 at 18:25
  • @Swapnil: I think at this point your only option may be to actually replace the entire `remove` method with your own. This is a little sketchy but overall should be OK as long as the original `remove` doesn't try to access any arguments beyond the one defined parameter. So then your new `remove` will simply invoke the original. I'll give an example in a comment below. –  Mar 09 '18 at 18:30
  • Wait, I may have misunderstood. If the call to `.remove()` is elsewhere, and doesn't pass a callback, then I don't know what you'd do. Can you post a full example that shows the actual situation? I'll check back later today. –  Mar 09 '18 at 18:34
  • @doodlemeister: Any sort of logic for remove function will work just the parameter should be the 'key'. No restriction in the remove function logic. – Swapnil Mar 09 '18 at 18:36
  • Then can't you just directly write in a function call? Then whoever invokes `.remove()` will be invoking your function. So it's just like the code I posted above, but `cb` is not a parameter, but is instead just some other function. –  Mar 09 '18 at 18:39
  • @doodlemeister: This is the code which gives call to remove function Truck.prototype.deliverOrder = function(customerId){ console.log("Delivering order for " + customerId); this.db.remove(customerId); } – Swapnil Mar 09 '18 at 18:40
  • `RemoteDataStore.prototype.remove = function(key){ this.get(key,function(serverResponse){ myFunc(key, serverResponse[0]["id"]); }); }; function myFunc(key, id) { console.log("The id to remove is :" + id); /*$.ajax(this.serverUrl + "/" + key ,{ type: "DELETE" });*/ }` –  Mar 09 '18 at 18:40
  • @doodlemeister: That's the perfect solution I was looking for! Thanks! – Swapnil Mar 09 '18 at 18:51
  • OP said `serverResponse` is an array `map()` returns a new array which I believe you can do if you curry the callback. – zer00ne Mar 09 '18 at 19:39
  • Swapnil: Just to be clear, this is what @NiettheDarkAbsol meant in his first comment where he write *"if you want to use it, do so in the callback"*. The thing to take away is that when it comes to async coding, you must use the data where it becomes available, even if that means just passing it to some other function that continues the execution. –  Mar 09 '18 at 22:06

0 Answers0