0

Writing in AngularJS, I've made an $http request to a JSON file within a service and I need to write an if statement to check whether the last value is more or less than the value before. It will only work if I place variables beneath the for loop, and this shouldn't be case.

When I console.log the length or the array it returns 0. I'm not sure whether the issue lies with my array, for loop or if statement. How do I iterate over the objects in the JSON file and push these items into an array?

app.factory('fxRate', ['$http', '$q', function($http, $q){

    var factory = {};

    factory.getFx = function() {
        return $http.get('../json/mcfx.json');
    }

    return factory;

}]);

app.controller('dashboard', ['$scope', 'fxRate', function($scope, fxRate){

    $scope.dailyFx = function() {
        fxRate.getFx().then(function(response) {
            //handle response or data
            var rates = [];
            var rateData = response.data.fxrate;
            var last_el = rates[rates.length - 1];
            var prev_el = rates[rates.length - 2];            
            console.log(rates)
            for (var i in rateData) {
               rates.push(rateData[i].usdToEur)
            }

            if(last_el > prev_el) {
                console.log('greater'); //0.9786
            } else {
                console.log('lesser'); //0.9232
            }        
        });
    }

    $scope.dailyFx();

}])

{
    "fxrate": [
        {
            "usdToEur": "0.94",
            "date": "23/05/2017"
        },
        {
            "usdToEur": "0.9232",
            "date": "24/05/2017"
        },
        {
            "usdToEur": "0.9786",
            "date": "25/05/2017"
        }       
    ]
}
2
  • Which variables are you talking about when you say : "It will only work if I place variables beneath the for loop" ? Commented May 24, 2017 at 14:25
  • var last_el and var prev_el Commented May 24, 2017 at 14:26

3 Answers 3

2

You're accessing rates.length and trying to address it like there should be members in it after you've assigned [] to it, which makes it an empty array.

I think you want something more like this:

app.controller('dashboard', ['$scope', 'fxRate', function($scope, fxRate){

    $scope.dailyFx = function() {
        var rates = [];
        var rateData = [];
        var last_el
        var prev_el

        fxRate.getFx().then(function(response) {
            //handle response or data

            rateData = response.data.fxrate;
            console.log(rates)
            for (var i in rateData) {
               rates.push(rateData[i].usdToEur)
            }
            last_el = rates[rates.length - 1];
            prev_el = rates[rates.length - 2];            

            if(last_el > prev_el) {
                console.log('greater'); //0.9786
            } else {
                console.log('lesser'); //0.9232
            }        
        });
    }

    $scope.dailyFx();

}])

You're basically doing it correctly, just in the wrong order. In your code, the rates array will always be empty when these 2 lines execute:

var last_el = rates[rates.length - 1];

var prev_el = rates[rates.length - 2];     
Sign up to request clarification or add additional context in comments.

3 Comments

This is what I did and it worked, but I always thought it was best practice to keep all variables at the top, so just wondered if there was a more efficient way of writing the script to keep them there. Thanks for your time anyway
You can declare the variables at the top if you like but you still have to assign values to them in the appropriate order. I can edit the answer to reflect that, but if this is what you did, then why did you accept another answer?
Before I posted this question I did what you've answered with, but what I was looking for was something similar to @IAmKale's answer. If you could edit your answer to show that, that would be perfect
1

The issue is your then() statement. You define last_el and prev_el before your rates array is ever populated. Try this:

fxRate.getFx().then(function(response) {
  // Extract the USD to EUR rate from the returned response
  var rates = response.data.fxrate.map(function(rate) {
    return rate.usdToEur;
  });
  console.log(rates);

  // Grab the last and previous elements
  var last_el = rates[rates.length - 1];
  var prev_el = rates[rates.length - 2];            

  if(last_el > prev_el) {
      console.log('greater'); //0.9786
  } else {
      console.log('lesser'); //0.9232
  }        
});

You should now see something in the console:

console output from the above script

1 Comment

Brilliant! Exactly what I needed
1

Try this:

$scope.dailyFx = function() {
    fxRate.getFx().then(function(response) {
        //handle response or data
        var rates = [],
           rateData = response.data.fxrate,
           last_el, prev_el;

        for (var i in rateData) {
           rates.push(rateData[i].usdToEur)
        }

        if (rateData.length > 1) {
            last_el = rates[rateData.length - 1];
            prev_el = rates[rateData.length - 2];            
        }

        if (last_el > prev_el) {
            console.log('greater'); //0.9786
        } else {
            console.log('lesser'); //0.9232
        }        
    });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.