Passing value in function properly in AngularJS - javascript

I have the following function which takes variable description as parameter
$scope.relsingle = function(description) {
console.log(description);
var url = $scope.url+'/api/descrelation?limit=4&description='+description;
$http.get(url).success(function(data) {
console.log(data);
$scope.apgresponse = data;
})
};
I use the following approach to pass this value in the html page
ng-init="relsingle(prodres[0].description)"
This value of prodres[0].description comes from here.
And value of prodres comes from here
$scope.prodat = function(id) {
var uri = $scope.url+'/api/getproduct?productid='+id;
console.log(uri);
$http.get(uri).success(function(data) {
console.log(id);
console.log(data);
$scope.prodres = data;
})
};
when i log the value of description in console in the relsingle function.
console.log(description);
This gives me value undefined.

You can't do it like this with ngInit because it runs only once and when it happence variable prodres is not yet available because it comes from async call.
What you can however do is to make ngInit execute only after the value for prodres has been resolved:
<div ng-if="prodres" ng-init="relsingle(prodres[0].description)">...</div>
Because ngIf has higher priority ngInit will execute only after ngIf.

Well it is because it is because the array has not been evaluated in javascript.Use a call back function and store that array in a variable on the $scope scope.Then you can use it in the function

Related

Angularjs cannot add data service response to scope variable

I have a function in my controller which request dataservice for data and I am trying to add to current scope variable but it is giving me undefined error
$scope.affiliates = d.data;
if (isNaN($scope.affiliate_id)){
var i = 0;
while (i < $scope.affiliates.length){
var affiliate_id = $scope.affiliates[i].affiliate_id.replace(/["']/g, "");
DataService.getAffiliateConversionApiService(affiliate_id).then(function(apiData){
$scope.affiliates[i].apiData = apiData;//ERROR IN HERE
});
i++;
}
}
TypeError: $scope.affiliates[i] is undefined
I have also tried returning data from dataService and set it outside but it always returns empty.
How can i resolve this?
Don't forget that getAffiliateConversionApiService is returning a promise (which means it is an async operation) therefore your while block will execute for every possible i value before you even get the result from getAffiliateConversionApiService.
Let's imagine that $scope.affiliates.length is 6. When your callback code inside the then is executed, your i will be 7.
One solution is to use angular.forEach instead of the while. However, if you still want to use the while you will need to store the i value in another variable:
while (i < $scope.affiliates.length){
var index = i;
var affiliate_id = $scope.affiliates[i].affiliate_id.replace(/["']/g, "");
DataService.getAffiliateConversionApiService(affiliate_id).then(function(apiData){
$scope.affiliates[index].apiData = apiData;
});
i++;
}
This is not really an answer, but here is some debugging that should help you out.
Also, I switched from using a while loop to using angular's forEach
$scope.affiliates = d.data;
if (isNaN($scope.affiliate_id)){
console.log($scope.affiliates); // what does this return?
angular.forEach($scope.affiliates, function(value, index){
console.log(value); // output the affiliate, if any
var affiliate_id = value.affiliate_id.replace(/["']/g, "");
DataService.getAffiliateConversionApiService(affiliate_id).then(function(apiData){
console.log(apiData); // see what is returned
$scope.affiliates[index].apiData = apiData; // still an error?
});
});
}

Passing data to a function as a key and value

I have been trying to execute a function as follows, but am not succeeding.
var leagueSelect = "allLeagues";
loadTable("#loadLeaguesTable","php/leagueTable.php",'leagueSelect',leagueSelect);
The loadTable function:
function loadTable(tableDiv, tableURL, tableType, tableVal){
$.post(tableURL,{tableType:tableVal},function(data){
$(tableDiv).append(data);
});
}
I'm trying to send the values in the post in this format: { leagueSelect: leagueSelect }.
If I hard-code leagueSelect into my function in place of the tableType parameter in the $.post function, it works.
How am I supposed to send 'leagueSelect' properly in my function call?
I'm thinking the data[key] = value method but I didn't get that working either.
Thanks.
When you assign the variable you're actually creating a new object with the property tableType set to whatever the tableVal value is.
Instead you need to use the object[key] = val; syntax or pass the post data in directly like this:
var leagueSelect = "allLeagues";
loadTable("#loadLeaguesTable", "php/leagueTable.php", { leagueSelect: leagueSelect });
function loadTable(tableDiv, tableURL, postData) {
$.post(tableURL, postData, function(data) {
$(tableDiv).append(data);
});
}

Pass var to angular $resource success function

I've been going crazy over this and I think the answer is probably out there but I don't know the right way to ask Google the question.
Essentially I need a way to make a $resource call, and pass in some data that I want to then use in the success function.
app.controller('VariantListController', ['djResource', function(djResource){
var Variants = djResource('/ship-builder/variants/?format=json');
var Vehicle = djResource('/ship-builder/vehicles/:id', {id: '#id'});
this.variants = Variants.query(function(variants){
$(variants).each(function(){
console.log(this);
variantData = this;
var vehicleData = Vehicle.get({id:this.baseVehicle}, function(){
console.log(variantData);
})
})
});
}]);
In the above example, in the innermost success function, 'variantData' is always the value of the LAST entry from the previous level. This makes sense because the value was set by the last item in the array long before the success happens. I need a way though to have the value of the 'variantData' that was inexistince when the Vehicle.get() was called.
Does that make sense? I find it very hard to explain the issue.
You need to create a closure to make it work. Something like
this.variants = Variants.query(function(variants){
$(variants).each(function(){
getVehicleData(this);
})
});
function getVehicalData(variantData) {
var vehicleData = Vehicle.get({id:variantData.vehicleId}, function(){
console.log(variantData);
})
}
I am by no means an expert on the $resource service, but perhaps using the $promise.then method instead of the success callback would work.
$(variants).each(function(){
console.log(this);
variantData = this;
Vehicle.get({id:this.baseVehicle}).$promise.then(function() {
console.log(variantData);
});
});
Since the value in variantData may change before the success callback is actually called, you want to ensure the the callback has the original value stored.
var vehicleData = Vehicle.get({id:this.baseVehicle}, function(vData){
return function() {
console.log(vData);
}
}(variantData));
The above will create a new function with variantData stored in a closure.

nested angular http.get calls

I have a simple angular $http.get, which returns a json object, but I want the id from the json to do another $http.get. I can do this by nesting another $http.get with the first one, but this seems rather stupid. What is the best way to assign the id of the response, data.id, to a variable? I'm having some issues with variable scope; trying to simply assign the value to a variable.
$http.get('/api/v1/foo/userinfo?thunk='+thunk+'&bar='+bar).success(function(data) {
$scope.id = data.id
}).then(function(data){
$scope.id = data.data.id
});
Why don't you watch your variable, in this case $scope.id like this:
$scope.$watch('id', function() {
// Http request goes here
$http.get(...)
});
When you assigned any value to $scope.id your "watch function" will be triggered.
Can use callbacks to make it cleaner. Wrap your call in a function:
function startAJAX(thunk, bar, callback) {
$http.get('/api/v1/foo/userinfo?thunk='+thunk+'&bar='+bar).success(function(data) {
callback(data.id);
});
}
Then make the call and do your next http call:
startAJAX(thunk, bar, function(id) {
$http(id).....
});
});
Using a watch() method isn't necessary. Use callbacks, or if you want to be fancy use promises to keep things organized.
var callOnePromise = $http.get('/api/foo');
var callTwoPromise;
callOnePromise.success(function(data) {
callTwoPromise = $http.get('/api/bar/' + data.id);
});
callTwoPromise.success(function() {
//Cool stuff here.
});

Why is my controller property 'undefined' when I assign it the result of $resource query()?

I have a JSON data structure:
[
{
"title" :"a1",
"id" :"b1",
"name" :"c1"
},
{
"title" :"a2",
"id" :"b2",
"name" :"c2"
}
]
I am accessing is as an external JSON and parsed through a factory method. I want it to assign it to a Javascript variable in my controller.
function Control($scope,data)
{
var e=data.query(); /* getting the external JSON data */
alert(e[0].title);
}
It says that e[0] is undefined. Is there any other way I can assign it to a Javascript variable and then traverse through it? Please help.
Most likely, #Marty is correct. If you are using the query() method from the $resource service, it is asynchronous. This will likely do what you want:
data.query( function( data ) {
var e = data;
alert(e[0].title);
});
Okay, so $resource can be confusing like this... It immediately gives you a reference to the return object, but doesn't update the object until the asynchronous AJAX call returns... so...
If you put your return value from data.query() in a property on $scope, since it's $watched when you bind it in your view, you'll see it update. HOWEVER, if you're just trying to alert it, it will alert the value before it's been updated.. again because of the async aspect of $resource.
Otherwise, you can get the value the way that #MarkRajcok has shown in his answer.
Here is a psuedo-code illustration of ways you can use $resource query();
app.controller('FooCtrl', function($scope, $resource) {
var Bar = $resource('/Bar/:id', {id: '#id'});
// here, we get the result reference and stick it in the scope,
// relying on a digest to update the value on our screen.
$scope.data = Bar.query();
//OR
//here we already have a reference.
var test = Bar.query(function() {
//in here, test has been populated.
$scope.data2 = test;
});
alert(test); //not populated here, yet.
//OR
Bar.query(function(x) {
$scope.data3 = x;
});
});
This is all done so the object(s) returned can have functions pre-instantiated on them like $save(), etc.

Categories