0

I am trying to read a file in angular js where if the data is read successfully it will assign the content to a variable of an object else it will assign "NA" to that same variable.

function customer($scope, $http) {
    var i;
    $scope.courses = [{
        name: "CSE",
        capacity: "CSE.txt"
    }, {
        name: "IT",
        capacity: "IT.txt"
    }, {
        name: "ECE",
        capacity: "ECE.txt"
    }];

    for (i = 0; i < 3; i++)
        $http.get($scope.courses[i].capacity).then(function (success) {
            $scope.courses[i].capacity = success.data;
        }, function (error) {
            $scope.courses[i].capacity = "NA";
        });

}

var myApp = angular.module("myApp", []);
myApp.controller("customerobj", customer);

I try to access the following part in a normal table format

<td>ng-repeat="course in courses">{{course.capacity}}</td>

But every time I do that it's throwing an error: "Cannot set property 'capacity' of undefined" and showing the file names. Even though if the files are not found it is supposed to update the value to "NA". But it is not happening. Please help me out

5
  • Try to wrap your $http.get in function. Seems like issue with closures in javascript Commented Feb 16, 2017 at 5:24
  • @DarshakGajjar Because the error is "Cannot set property 'capacity' of undefined" which indicates that $scope.courses[i] is undefined. And because this is part of a loop it looks to me like it is a duplicate of the one I've linked Commented Feb 16, 2017 at 5:31
  • $scope.courses[i] is already defined in the array definition? Commented Feb 16, 2017 at 5:34
  • @SiddharthaChoudhury Can you check browser console? On which line the error is throwing? Commented Feb 16, 2017 at 5:37
  • $scope.courses[i].capacity = "NA"; - this line Commented Feb 16, 2017 at 5:39

4 Answers 4

2

Wrap your http service call in another function like below and call that function in loop so that loop index i value will persist in function scope.

Update:

If you don't want a separate function you can use anonymous functions also

Solution 1

for (i = 0; i < 3; i++) {
    (function (index) {
        $http.get($scope.courses[index].capacity).then(function (success) {
            $scope.courses[index].capacity = success.data;
        }, function (error) {
            $scope.courses[index].capacity = "NA";
        });
    } (i))
}

Solution 2

for (i = 0; i < 3; i++) {
  serviceCall(i)
}

function serviceCall(index) {
  $http.get($scope.courses[index].capacity).then(function (success) {
    $scope.courses[index].capacity = success.data;
  }, function (error) {
    $scope.courses[index].capacity = "NA";
  });
}
Sign up to request clarification or add additional context in comments.

4 Comments

It is working. Sir, if you don't mind, can you plz explain it a little bit?
@SiddharthaChoudhury It is called as closure. If you put the function outside of the loop, each index variable is bound to the function otherwise they will share the same variable. I would recommend to have a look on closure inside loops
That's the solution of the duplicate. You should instead have voted to close this one as a dupe...
@Andreas Though the underlying concept is similar, OP was unable to understand the context even after we both commented. Then only I had given answer.
1

Use let in for loop

for (let i = 0; i < 3; i++) { 
...... 
}

Ref:

http://caniuse.com/#search=let https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/let

Comments

0

code is corret. but for loop is not. when you add console.log(i) to error function you see 3. but your array has 3 member. http request is async. for loop can not wait its response. use Gangadhar Jannu solution.

Comments

0

I think using let in for loop is the much better approach to handle this type of cases. Let in the loop can re-binds it to each iteration of the loop, making sure to reassign it the value from the end of the previous loop iteration, so it can be used to avoid issue with closures

for (let i = 0; i<3;i++) {

}

everytime when async code inside for loop will be executed it will get correct value of i

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.