Ajax functie return
Ik heb een vraag mbt de return van een ajax waarde uit een functie.
Dit is mijn functie:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function getPrice(productcode, quantity, specifications){
var url = "api-url-with-security-token";
var call = $.ajax({
type: "POST",
url: url,
data: {
productcode: productcode,
quantity: quantity,
specifications: specifications
}
});
call.done(function(data){
var result = JSON.parse(data);
if ('status' in result) {
console.log(result.prices.total);
price = result.prices.total;
return price;
}else{
console.log("ERROR price request");
return 0;
}
});
}
var url = "api-url-with-security-token";
var call = $.ajax({
type: "POST",
url: url,
data: {
productcode: productcode,
quantity: quantity,
specifications: specifications
}
});
call.done(function(data){
var result = JSON.parse(data);
if ('status' in result) {
console.log(result.prices.total);
price = result.prices.total;
return price;
}else{
console.log("ERROR price request");
return 0;
}
});
}
Als ik deze functie aanroep zoals dit:
Dan wordt in mijn console de variabele price 'undefined', terwijl de console.log functie IN mijn functie wel degelijk de correcte waarde teruggeeft.
Dit is waarschijnlijk omdat de functie al een return doet, nog VOOR de ajax-request een antwoord heeft gegeven. Maar hoe zorg ik ervoor dat de functie pas een return mag doen wanneer de ajax correct is uitgevoerd en een antwoord heeft gegeven?
Bedankt!
Gewijzigd op 19/01/2018 12:35:59 door Liefhebber Laravel
Geef de return op regel 20 ook eens een waarde.
De functie getPrice() retourneert niks, die maakt alleen een asynchrone call. Pas in de done heb je je antwoord, maar dan is de getPrice call allang verleden tijd. Wat je dus met de price van regel 16/17 wilt doen zul je daar moeten doen (of een callback functie meegeven aan getPrice().
En hoe pas ik dit dan toe in mijn voorbeeld?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
function getPrice(a,b,c,callback){
//...
call.done(function(data){
//...
callback(price);
});
}
//vanuit ander script
getPrice(1,2,3,function(price){
//doe ding met price
});
//...
call.done(function(data){
//...
callback(price);
});
}
//vanuit ander script
getPrice(1,2,3,function(price){
//doe ding met price
});
Je kunt ook je "call" object retourneren, en dan in je "andere script" de done() d'r aan knutselen. Maar in beide gevallen zul je niet "synchroon" (= direct) een antwoord krijgen. De asynchrone call heeft even tijd nodig, en de code waarin je getPrice() hebt aangeroepen loopt gewoon door.
@Rob Doemaarwat: dus de code waarin ik m'n getPrice() aanroep, kan onmogelijk 'on-hold' gezet worden tot deze asynchrone call volledig uitgevoerd is?
Via callback, promises, etc. bereik je wat je wilt bereiken, nl verschil tussen 'nu' en 'later'.
PS er bestaat ook iets als blocking AJAX, maar dat terzijde
Gewijzigd op 19/01/2018 15:43:00 door Nick Vledder
Ik wil eigenlijk gewoon een functie (die in de scripts.js staat) die ergens via een API een prijs ophaalt, en die prijs teruggeeft. Daarna wil ik in mijn algemene pagina een script onderaan toevoegen die gewoon dit doet in deze stappen:
- een 'on-hold' div zichtbaar maken (met een zandlopertje en tekst "prijs wordt opgehaald")
- de functie van hierboven aanroepen om de prijs aan te vragen
- als de prijs binnen is, DAN PAS de on-hold div onzichtbaar maken
- de binnengekomen prijswaarde met jQuery in het veld plaatsen (iets zoals $('#price').val(price);)
Dit moet toch op een relatief eenvoudige manier te bouwen zijn?
Graag had ik hiervan een mooi voorbeeld gehad...
Bedankt alvast!
1. loader kan met puur css,
2. in html kun je een div maken met een class="loader" en id="response" (voorbeeldnamen),
3. in één simpele AJAX-snippet (in JS) kun je het PHP-script aanroepen en zodra de response er is:
A. de class="loader" verwijderen;
B. de HTML-response van de server in de div met id="response" plaatsen;
Voorbeeldje in JS:
$.ajax({url: "<url>script.php", success: function(result){
$("#response").removeClass();
$("#response").html(result);
}});
That's it.
PS In vbd even een method: "GET", maar met method: "POST" is het voorbeeld niet wezenlijk anders
Gewijzigd op 19/01/2018 20:27:34 door Nick Vledder