Call function inside ng-repeat to retrieve value - javascript

I'm having this situation I'm iterating over a json response from an endpoint:
chunk of controller code:
$http({
method: 'GET',
url: 'http://mywebsite.com/api/v1/stores/'
}).
success(function(data, status, headers, config) {
$scope.stores = data;
}).
error(function(data, status, headers, config) {
$scope.name = 'Error!';
});
and on my html view side I've got this:
<tbody>
<tr ng-repeat="store in stores">
<td>{{store.name}}</td>
<td> {{store.type}} </td>
<td><span ng-repeat="client in retrieveClientName(store.client_id)">
{{client.name}}
</span>
</td>
<td>{{store.address}}</td>
</tr>
</tbody>
As you can see I'm trying to retrieve the client name using a function that receives an store.client_id from the values inside the stores array. Normally using a function triggered by a ng-click will be easy but how can I achieve this "on the fly" while I'm iterating?.
Because executing this I get a kind of infinite loop that breaks all apart.
here is the code of the function that returns client name on the controller side:
$scope.retrieveClientName = function(id) {
$http({
method: 'GET',
url: 'http://mywebsite.com/api/v1/clients?client_id='+id
}).
success(function(data, status, headers, config) {
return $scope.clients=data;
}).
error(function(data, status, headers, config) {
$scope.name = 'Error!';
});
}
I have also try using mg-init directive
<td ng-init="clients=retrieveClientName(store.client_id)"><span ng-repeat="client in clients">{{client.name}}</span></td>

One way would be get all data when you get the stores back
$http({
method: 'GET',
url: 'http://mywebsite.com/api/v1/stores/'
}).
success(function(data, status, headers, config) {
$scope.stores = data;
angular.forEach($scope.stores, function(store){
$scope.retrieveClientName(store.client_id).then(function(clients){
store.clients = clients;
});
});
}).
error(function(data, status, headers, config) {
$scope.name = 'Error!';
});
Edit: I would change the structure a bit for cleaner code
$scope.retrieveClientName = function(store) { // pass in store so we can attach results here
$http({
method: 'GET',
url: 'http://mywebsite.com/api/v1/clients?client_id='+store.client_id
}).
success(function(data, status, headers, config) {
return store.clients = data; // attach result in object
}).
error(function(data, status, headers, config) {
$scope.name = 'Error!';
});
}
$http({
method: 'GET',
url: 'http://mywebsite.com/api/v1/stores/'
}).
success(function(data, status, headers, config) {
$scope.stores = data;
angular.forEach($scope.stores, function(store){
$scope.retrieveClientName(store); // no need .then here
});
}).
error(function(data, status, headers, config) {
$scope.name = 'Error!';
});
<tbody>
<tr ng-repeat="store in stores">
<td>{{store.name}}</td>
<td> {{store.type}} </td>
<td><span ng-repeat="client in store.clients"> <!-- use data here -->
{{client.name}}
</span>
</td>
<td>{{store.address}}</td>
</tr>
</tbody

You must understand that $http jest asynchronous, so Your response will be back after all ng-repeat, so such thing must be done in controller in $q.all and after that render view with ng-repeat.
So do foreach on stores and in foreach add to array, next use this array in $q.all, after $q.all render view.

The retrieveClientName function is wrong: the $http return a promise, the return value of success callback is not the return value of the function and you can't bind the ng-repeat to a promise, try this one:
$scope.retrieveClientName = function(id) {
return $resource('http://mywebsite.com/api/v1/clients?client_id='+id).query();
}
Don't forget to include the ngResource dependency.

Related

Create a custom http service that will request external JSON file. pure angularjs only

I have a http service which will call external json files and load it into a grid.
My problem is i need to create a custom http service so that i could use the same in different controllers. The function of that custom service should be the same (requesting external Json file)
$http.get('../JSON/permanentEmployees.json').
success(function(data, status, headers, config) {
$scope.masterArray = data;
}).
error(function(data, status, headers, config) {
$scope.errorMessage = "Requested grid data file does not exist";
});
This is my current http service. Any help would be appreciated.Please use angularjs only
wrap the code in a factory and use it. I think its better to use a factory in this situation, refer here. P.S. unable to create a mockup of the request to JSON, please check with your JSON.
JSFiddle: here
app.factory('customHTTPService', function($http){
return {
getRequest: function(url) {
return $http.get(url).
success(function(data, status, headers, config) {
return {data: data, errorMessage: "Success"};
}).
error(function(data, status, headers, config) {
return {data: "", errorMessage: "Requested grid data file does not exist"};
});
}
}
});
In the controller you can do
app.controller('MyController', function MyController($scope, customHTTPService) {
$scope.data = customHTTPService.getRequest('../JSON/permanentEmployees.json').data;
});

Get value from outside ng-repeat in angular

How can i get a value from outside an ng-repeat?
This is my function to get values from json
function($scope, $http) {
$http.get('https://www.mywebsite.com/images/getimages.php').
success(function(data, status, headers, config) {
$scope.walls = data.walls;
console.log($scope.walls);
}).error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
then i have a table:
<tr ng-repeat="wall in walls">
<td>{{wall.id}}</td>
<td>{{wall.link}}</td>
</tr>
i would show in a div outside the table and so outside the ng-repeat, the {{wall.link}} selected from the td. How can i do it?
You can implement controller function to set selected wall object:
function ($scope, $http) {
$http.get('https://www.mywebsite.com/images/getimages.php')
.success(function (data, status, headers, config) { /*...*/ })
.error(function (data, status, headers, config) { /*...*/ });
$scope.select = function (wall) {
$scope.selectedWall = wall;
};
}
and the in HTML you would use
<table>
<tr ng-repeat="wall in walls">
<td>{{wall.id}}</td>
<td>
{{wall.link}}
</td>
</tr>
</table>
<div>{{selectedWall.link}}</div>

Why Angularjs continuously call method when send a get request?

I am new in angularjs. I am try to send a get request to my Web-Api 2 project. But I don't understand why its continuously call my method. I am following AngularJs $http for this.
Here is my error:
My Code is :
<script src="~/Scripts/jquery-2.1.0.js"></script>
<script src="~/Scripts/angular.min.js"></script>
<script>
function loginCtrl($scope, $http) {
$scope.name = function () {
console.log("Add Call");
$http({ method: 'GET', url: 'http://localhost:15229/api/values' }).
success(function (data, status, headers, config) {
console.log(data);
}).
error(function (data, status, headers, config) {
console.log(data);
});
};
}
</script>
<div lang="en" ng-app="" ng-controller="loginCtrl">
{{name()}}
</div>
You don't give enough context information for me to be sure of what you want to achieve. Especially I don't know what returns your api. So I will assume It returns the value you want to display. Your code should look more like this:
function loginCtrl($scope, $http) {
$scope.init = function () {
console.log("Add Call");
$http({ method: 'GET', url: 'http://localhost:15229/api/values' }).
success(function (data, status, headers, config) {
console.log(data);
$scope.name = data;
}).
error(function (data, status, headers, config) {
console.log(data);
});
};
}
<div lang="en" ng-app="" ng-controller="loginCtrl" ng-init="init()">
{{name}}
</div>
You should affect $scope.name in the success callback.
name should be a variable, not a function.
And the ng-init attributes defines the method to be invoked when instanciating the controller. In this case it will invoke the init() method of your controller.

How to pass URL params in angular $http

I'm converting a server side CRUD app to Angular.js and have a small problem.
I'm getting my data with $http and display all the data via ng-repeat. I want to make users able to click and a specific item and redirect them to the resource.
So how can I pass a URL param to the $http get call dynamically?
Here's how I built the link to the resource (car.id = 3)
<a ng-href="/#/cars/{{car.id}}">Edit</a>
The link should go to http://local.dev/#/cars/3
So how do I bind the dynamic url in my controller?
Here's a stripped down version of my controller
App.controller('CarIndexCtrl', ['$scope', '$http', '$location', function ($scope, $http, $location) {
$scope.car = {};
$http({
method: 'GET',
url: $location.$$url,
})
.success(function (data, status, headers, config) {
$scope.car = data;
})
.error(function (data, status, headers, config) {
// error
});
}]);
So I'm interested to bind the URL the angular way. The above solution works, but feels very much like a hack. I'm not that familiar with Angular, so I like to stick to the defaults for now. I might consider restangular or ng-resource at a later time though...
the above solution works, but feels very much like a hack.
I don't think its hack or something messy.
I would generate URL list in controller (from my view its better for code maintenance) without appending in HTML. Something like:
$scope.urlList = [];
$http({
method: 'GET',
url: $location.$url,
})
.success(function (data, status, headers, config) {
$scope.car = data;
$scope.urlList.push("/#/cars/" + data.id);
})
.error(function (data, status, headers, config) {
// error
});
After in HTML:
<li ng-repeat="url in urlList" repeat-done="layoutDone()" ng-cloak>
<a ng-href="{{url}}">Edit</a>
</li>
BTW, I suggest you to use some loader because URL links we generate from promise (aka async) therefore with delay.
Demo Fiddle
In your app.js do something like this
var app = angular.module('YourAPP');
app.config(function ($routeProvider) {
$routeProvider
.when('/cars/:CarID', {
templateUrl: 'app/views/cars.html',
controller: 'CarIndexCtrl'
});
});
And in your controller
App.controller('CarIndexCtrl', ['$scope', '$http', '$location', '$routeParams', function ($scope, $http, $location, $routeParams) {
$scope.car = {};
$scope.carid = $routeParams.CarID;
$http({
method: 'GET',
url: $location.$$url,
})
.success(function (data, status, headers, config) {
$scope.car = data;
})
.error(function (data, status, headers, config) {
// error
});
}]);
And use the carid in wherever in your controller. Hope it helps.

Page reload using angularJs

I am newbie to angularJS. I have started learning with CRUD operation. I am getting a problem that when I delete an entry then the page should reload
I have gone through $location and $route too. and implementing as follow :
config
app.config( function ( $locationProvider, $routeProvider ) {
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix = '!';
$routeProvider.when('/', {
templateUrl: '/views/index.html',
controller: 'MainCtrl'
});
$routeProvider.when('/this',{
templateUrl: '/views/about.html',
controller: 'MainCtrl'
});
});
and when action success then I am writing as :
$location.path('/this');
but when I do this then the url changes from http://localhost/someapp to http://this but the page does not refresh. What should I do in this case please help me guys ?
Edit :
Here is my deletion code :
$scope.deletecode = function (id) {
name = '';
if (confirm("are you sure to Delete the name")) {
$http({
method: 'POST',
url: 'rohit.php',
data: {
"name": name,
"id": id,
"delete": "true"
},
}).
success(function (data, status, headers, config) {
alert("data deleted successfully");
$location.path('/this');
}).
error(function (data, status, headers, config) {
alert("Unable to load data.");
});
} else {
alert("Data deletion cancelled by user ... ");
}
};
On init I am getting the data from a php file :
$http({
method: 'GET',
url: 'test.php'
}).
success(function (data, status, headers, config) {
$scope.samples = data;
}).
error(function (data, status, headers, config) {
alert("Unable to load data.");
});
all the data is stored in $scope.samples which returns two things user_id and name
Your http request is deleting the item from your server, but you are not deleting it from your client-side code, which is why your view is not updating. You want to remove it from you client-side code as well once it has been removed from the server:
// all items in an array
$scope.items = [item1, item2];
// delete an item
$scope.deletecode = function (id) {
name = '';
if (confirm("are you sure to Delete the name")) {
$http({
method: 'POST',
url: 'rohit.php',
data: {
"name": name,
"id": id,
"delete": "true"
},
}).
success(function (data, status, headers, config) {
alert("data deleted successfully");
// at this point, the item has been deleted from your server
// remove it from $scope.items as well
// removes 1 item at index idx
$scope.items.splice(idx, 1);
}).
error(function (data, status, headers, config) {
alert("Unable to load data.");
});
} else {
alert("Data deletion cancelled by user ... ");
}
};

Categories