0

I have a little currency exchange function going in a website and it works fine but today I've been asked to add the possibility of registering the best exchange rate and from then on being able to retrieve it and compare it to today's exchange rate.

So the snippet of the original function is the following (where exchangepair is set by the user -- ex. 'USDEUR'):

<script type="text/jscript">
    function doexchange(exchangepair) {
        $.ajax({
            url: 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22'+exchangepair+'%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=',
            success: function(response) {
                successCallback(response);
            },
            error: function(response) {
                //Error display
            }
        });
    }

    function successCallback(responseObj){
        var stringObj = JSON.stringify(responseObj),
            exchange = JSON && JSON.parse(stringObj) || $.parseJSON(stringObj),
            exchangerate = exchange.query.results.rate.Rate;
        //Do stuff with the exchange rate
    }
</script>

All of this works perfectly. So I went ahead and created some more code that registers today's exchange rate as the best whenever the user click the UPDATE button. I had this be registered in an XML file, as it's the most practical solution at this time.

So now I need to get the file read and the data parsed AND compared with the daily exchange rate data... This is where I hit a wall. In order to read the XML file I need an AJAX call and I can't have two separate functions with two separate AJAX calls. So the ideal thing would be to make a generic function with a generic AJAX call and just change the variables in each case... but the thing is I need to get both sets of data at the same time and compare them. I need to get the exchange rate of the day from Yahoo Currency and get the best recorded rate from that XML and then compare the two to be able to tell the user if the best rate needs updating to today's rate or not.

So far I've been at this over 5 hours and my head is about to explode. I've already lost track of what I've been doing and can't see any way out of this mess.

For what it's worth, this is the second AJAX function I need:

<script type="text/jscript">
    function getbestexchange(exchangepair) {
        $.ajax({
            type: "GET" ,
            url: "best"+exchangepair+".xml" ,
            dataType: "xml" ,
            success: function(xml) {
                bestrate = $(xml).find('rate').text();
            }
        });
    });
</script>

So what I would need is to compare this last function's resulting data passed through the bestrate variable with the first the successCallback() function's resulting data passed through the exchangerate variable.

If anyone out there could give me a hand and help me get to out of the problem of having to get data from both these places and then compare them, I would be greatly obliged!

EDIT: Following @guest271314's contribution and comments, I've created a jsfiddle to show you guys where I'm at. I've gone ahead and made the changes @guest271314 recommended but still I can't get this to work; it carries on failing at the .ajax()call for the XML file. The XML file is, however, up and running.

function doexchange(exchangepair) {
  // added `return`
  return $.ajax({
    url: 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22' + exchangepair + '%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback='
  }).then(successCallback);
}

function successCallback(responseObj) {
  var stringObj = JSON.stringify(responseObj),
    exchange = JSON && JSON.parse(stringObj) || $.parseJSON(stringObj),
    exchangepair = exchange.query.results.rate.id,
    exchangerate = parseFloat(exchange.query.results.rate.Rate).toFixed(2),
    exchangedate = exchange.query.results.rate.Date;
  $('#todaysrate').find('.pair').html(exchangepair);
  $('#todaysrate').find('.rate').html(exchangerate);
  $('#todaysrate').find('.date').html(exchangedate);
  // added `return`
  return exchangerate
}

function getbestexchange(exchangepair) {
  // added `return`
  return $.ajax({
    type: "GET",
    url: "http://chiennuperou.com/besthistoric" + exchangepair + ".xml",
    dataType: "xml"
  }).then(function(xml) {
    alert('Hey, I\'m working!');
    bestpair = $(xml).find('pair').text();
    bestrate = $(xml).find('rate').text();
    bestdate = $(xml).find('date').text();
    $('#bestrate').find('.pair').html(bestpair);
    $('#bestrate').find('.rate').html(bestrate);
    $('#bestrate').find('.date').html(bestdate);
    // added `return`
    return bestrate
  });
};

$.when(doexchange( /* value */ ), getbestexchange( /* value */ ))
  .then(function(exc, bestexc) {
    // do comparision stuff
    console.log(exc[0], bestexc[0])
  }, function err(jqxhr, textStatus, errorThrown) {
    $('#error').html(errorThrown);
    console.log(errorThrown)
  })

$('#refresh').click(function() {
  $('#todaysrate').find('.pair').html('. . .');
  $('#todaysrate').find('.rate').html('. . .');
  $('#todaysrate').find('.date').html('. . .');
  $('#bestrate').find('.pair').html('. . .');
  $('#bestrate').find('.rate').html('. . .');
  $('#bestrate').find('.date').html('. . .');
  $('#error').html('');
  doexchange('USDEUR');
  getbestexchange('USDEUR');
})

var exchangepair;
doexchange('USDEUR');
getbestexchange('USDEUR');
span {
  font-weight: bold;
  color: #f00;
}
#refresh {
  display: inline-block;
  color: white;
  background: gray;
  padding: 5px 7px;
  margin-top: 10px;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="todaysrate">Today's rate (<span class="date"></span>) for <span class="pair"></span> is 1.00/<span class="rate"></span>
</div>
<div id="bestrate">Best rate (<span class="date"></span>) for <span class="pair"></span> is 1.00/<span class="rate"></span>
</div>
<div id="error">
</div>
<div id="refresh">
  Refresh
</div>

https://jsfiddle.net/48n0u4gv/17/

QuestionerNo27
  • 610
  • 6
  • 14
  • 30

1 Answers1

0

You could try using $.when()

function doexchange(exchangepair) {
    // added `return`
    return $.ajax({
        url: 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22'+exchangepair+'%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback='
    }).then(successCallback);
}

function successCallback(responseObj){
    var stringObj = JSON.stringify(responseObj),
        exchange = JSON && JSON.parse(stringObj) || $.parseJSON(stringObj),
        exchangerate = exchange.query.results.rate.Rate;
    //Do stuff with the exchange rate
    // added `return`
    return exchangerate
}

function getbestexchange(exchangepair) {
    // added `return`
    return $.ajax({
        type: "GET" ,
        url: "best"+exchangepair+".xml" ,
        dataType: "xml"
    }).then(function(xml) {
         bestrate = $(xml).find('rate').text();
         // added `return`
         return bestrate
    });
};

$.when(doexchange(/* value */), getbestexchange(alue/* v */))
.then(function(exc, bestexc) {
  // do comparision stuff
  console.log(exc[0], bestexc[0])
}, function err(jqxhr, textStatus, errorThrown) {
      console.log(errorThrown)
})

at first glance, I see I'd be losing the error handling on the original function.

function err() {} at .then() should handle rejected jQuery promise returned passed as parameter to $.when()

// do asynchronous stuff
function failOrSucceed(t, type) {
  return $.Deferred(function(d) {  
    setTimeout(function() {    
      d[type](type === "reject" 
              ? new Error(type + "ed jQuery promise") 
              : type + "d jQuery promise")
    })
  }, t).then(function(result) {  
    return result
  })
}

$.when(failOrSucceed(1000, "reject"), failOrSucceed(900, "resolve"))
.then(function(a, b) {
  console.log(a, b)
}
// handle error, rejected promise returned from `$.when()`
, function err(e) {
  console.log(e)
});

$.when(failOrSucceed(2000, "resolve"), failOrSucceed(2100, "resolve"))
.then(function(a, b) {
  // do stuff with resolved promise values
  console.log(a, b)
}
// handle error, rejected promise returned from `$.when()`
, function err(e) {
  console.log(e)
})
<script src="https://code.jquery.com/jquery-git.js"></script>

jsfiddle https://jsfiddle.net/4denw07e/

guest271314
  • 1
  • 15
  • 104
  • 177
  • Hi, and thanks a lot for your answer! I haven't yet tried this to see if it works but, at first glance, I see I'd be losing the error handling on the original function. – QuestionerNo27 Mar 16 '16 at 23:53
  • @QuestionerNo27 If an error is returned from one of the jQuery promise values as parameters to `$.when()`, `err` function at `.then()` should handle the error – guest271314 Mar 16 '16 at 23:57
  • Yep, caught it in the end. I must be very tired! But I can't get this to work for me... – QuestionerNo27 Mar 17 '16 at 00:09
  • @QuestionerNo27 _"But I can't get this to work for me"_ Can you create jsfiddle http://jsfiddle.net to demonstrate ? See updated post – guest271314 Mar 17 '16 at 02:39
  • Hi again, and thanks for your help. I didn't mean the error handler wasn't working for me; I meant the entire code wasn't working for me. Here, I've created a jsfiddle of what I have up to now. https://jsfiddle.net/48n0u4gv/17/ Notice where I placed the `alert()` in the second `.then()` after the second `.ajax()`; this is not being called, so I'm assuming the problem is occurring when trying to get the XML, which was happening to me on the original code. If you go straight to the XML here you'll see it's working: http://chiennuperou.com/besthistoricUSDEUR.xml Thanks again for your help! – QuestionerNo27 Mar 17 '16 at 14:39
  • @QuestionerNo27 `url` "chiennuperou.com/besthistoricUSDEUR.xml" logs `XMLHttpRequest cannot load http://chiennuperou.com/besthistoricUSDEUR.xml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://fiddle.jshell.net' is therefore not allowed access.` at `console`. See http://stackoverflow.com/questions/20035101/no-access-control-allow-origin-header-is-present-on-the-requested-resource? – guest271314 Mar 17 '16 at 14:58
  • Thanks again for your input. I feared as much... The problem is that the XML file is only being gotten from outside its domain for the jsfiddle. In the original, the XML is right there, in the same domain, and I still have the same issues. – QuestionerNo27 Mar 18 '16 at 00:02
  • @QuestionerNo27 What is the issue ? Can you create a jsfiddle http://jsfiddle.net to demonstrate ? – guest271314 Mar 18 '16 at 00:05