Permalänk

Javascript, jQuery & Ajax-anrop

Jag står inför en liten utmaning i ett projekt jag grejar med. Det borde vara busenkelt men jag stöter på problem dessvärre, kanske någon kan tipsa mig i rätt riktning?
* Jag ska modifiera en javascriptfunktion som validerar ett formulär. Funktionen förväntas returnera true/false om allt är ok eller inte, detta kan jag inte påverka.
* All validering sker i Javascript/jQuery, förutom en validering som behöver vara ett REST-anrop via jQuery/Ajax. Den här REST-valideringen ska dock bara utföras om ett visst input-fält finns på sidan (visas inte under vissa förutsättningar).
* För enkelhetens skulle jag vilja ha ett "async: false" på ajax-anropet men det verkar inte stödas längre.

Jag har problem med flödet här i och med ajax-anropet eftersom det blir asynkront. Jag kan inte returnera true/false via success: eller error: då det inte skickas ner till funktionen som ska ha det.
Jag har googlat sönder nätet hur jag ska göra det här enkelt men inte hittat nått bra sätt än. Jag skulle vilja göra nått i stil med
var result = validateStuff(), d.v.s. en funktion som gör rest-anropet och sen returnerar just true/false till huvudfunktionen men det var inte helt uppenbart..

Hoppas någon orkar läsa och förstår någorlunda vad jag är jag ute efter. Tips skulle uppskattas!

Visa signatur

Dator: MB: Gigabyte Z390 M GAMING mATX | CPU: Intel Core i9 9900K 3.6 GHz (Haswell) | RAM: Corsair 16GB (KIT) 3200Mhz Vengeance LPX | Grafikkort: ASUS GeForce RTX 3060 12GB PHOENIX V2 (LHR) | Chassi: Fractal Design Mini | PSU: Corsair RM750X 750W v2 | Optisk: ASUS BW-12B1ST Blu-Ray/DVD brännare | CPU-kylare: Noctua NH-U12S | Operativ: Windows 11 | Scanner: Canon Canoscan 9000F
Övrigt: Nintendo Switch, NES Mini, SNES Mini, Nintendo New 3DS, NES, Famicom AV, Famicom Disk System, PS3, PS5, AppleTV 4K, Synology NAS DS923+ (32GB), iPhone 14 Pro 128GB, LG OLED 55C2,

Permalänk
Medlem

Du borde ju kunna resolva en asynkron metod med promises i javascript

Permalänk
Skrivet av oRBIT2002:

Jag står inför en liten utmaning i ett projekt jag grejar med. Det borde vara busenkelt men jag stöter på problem dessvärre, kanske någon kan tipsa mig i rätt riktning?
* Jag ska modifiera en javascriptfunktion som validerar ett formulär. Funktionen förväntas returnera true/false om allt är ok eller inte, detta kan jag inte påverka.
* All validering sker i Javascript/jQuery, förutom en validering som behöver vara ett REST-anrop via jQuery/Ajax. Den här REST-valideringen ska dock bara utföras om ett visst input-fält finns på sidan (visas inte under vissa förutsättningar).
* För enkelhetens skulle jag vilja ha ett "async: false" på ajax-anropet men det verkar inte stödas längre.

Jag har problem med flödet här i och med ajax-anropet eftersom det blir asynkront. Jag kan inte returnera true/false via success: eller error: då det inte skickas ner till funktionen som ska ha det.
Jag har googlat sönder nätet hur jag ska göra det här enkelt men inte hittat nått bra sätt än. Jag skulle vilja göra nått i stil med
var result = validateStuff(), d.v.s. en funktion som gör rest-anropet och sen returnerar just true/false till huvudfunktionen men det var inte helt uppenbart..

Hoppas någon orkar läsa och förstår någorlunda vad jag är jag ute efter. Tips skulle uppskattas!

Tänker du något i stil med att `var result = await ValidateStuff()` där du vill ha tillbaka true/false inuti "result"-variabeln och sedan ska du göra något med den beroende på om den är sann/falsk? Är problemet då att ValidateStuff() som ska innehålla AJAX-anropet inte tycks vilja returnera en Promise? (dvs., Resolve/Reject)

Om jag förstått rätt så bör du kanske kunna skapa en funktion som returnerar new Promise där svaret från AJAX-anropet (true/false) då blir resolve/reject vilket i sin tur kan användas för att göra något beroende på vad som lagras i: `var result = await ValidateStuff()`?

Jag skulle behöva se kod innan jag kan säga något mer!

Mvh,
WKL.

Visa signatur

"Den säkraste koden är den som aldrig skrivs"

Permalänk

Jag kan inte ha "await ValidateStuff() i en funktion som inte är async och jag kan inte förändra det.
Koden ser ut nått i den här stilen i dagsläget.

function validateForm() {

var isOK = true;
... validera massa fält, sätt isOK = false om något test failar

// Såhär nedan tror jag att jag skulle vilja ha det för rest-anrops-testet
var result = ValidateStuff();
if (result === false)
isOK = false;

return isOK;
}

function ValidateStuff() {
--- kör ajaxanrop och returnera true eller false beroende på hur valideringen gick...
}

Visa signatur

Dator: MB: Gigabyte Z390 M GAMING mATX | CPU: Intel Core i9 9900K 3.6 GHz (Haswell) | RAM: Corsair 16GB (KIT) 3200Mhz Vengeance LPX | Grafikkort: ASUS GeForce RTX 3060 12GB PHOENIX V2 (LHR) | Chassi: Fractal Design Mini | PSU: Corsair RM750X 750W v2 | Optisk: ASUS BW-12B1ST Blu-Ray/DVD brännare | CPU-kylare: Noctua NH-U12S | Operativ: Windows 11 | Scanner: Canon Canoscan 9000F
Övrigt: Nintendo Switch, NES Mini, SNES Mini, Nintendo New 3DS, NES, Famicom AV, Famicom Disk System, PS3, PS5, AppleTV 4K, Synology NAS DS923+ (32GB), iPhone 14 Pro 128GB, LG OLED 55C2,

Permalänk
Skrivet av oRBIT2002:

Jag kan inte ha "await ValidateStuff() i en funktion som inte är async och jag kan inte förändra det.
Koden ser ut nått i den här stilen i dagsläget.

function validateForm() {

var isOK = true;
... validera massa fält, sätt isOK = false om något test failar

// Såhär nedan tror jag att jag skulle vilja ha det för rest-anrops-testet
var result = ValidateStuff();
if (result === false)
isOK = false;

return isOK;
}

function ValidateStuff() {
--- kör ajaxanrop och returnera true eller false beroende på hur valideringen gick...
}

Då kommer jag inte på något annat sätt än "ful-lösningen" att skicka med nuvarande isOK-värdet till funktionen som ska köra AJAX-anropet:

function validateForm() { var isOK = true; // Validate stuff then pass on current isOK value return validateStuff(isOK); } function ValidateStuff(isOK) { // Kör AJAX anrop och sätt boolean-värdet för isOK innan det returneras till slut på hur AJAX-valideringen gick... return isOK; // Sätt denna return inuti AJAX-koden så den skickas efter AJAX-boolean-svaret. }

Fast jag får någon magkänsla av att det där inte kommer att fungera utan att validateForm() kommer att betraktas som färdig innan isOK har hunnit fått något slutgiltigt värde? 🤔 validateForm() bör returnera det senaste tilldelade värdet till isOK innan AJAX-anropet har hunnit blivit färdigt? I och med detta är kanske varför du inte hittar något svar online om du inte får använda async/await. Jag har funderat på "Async IIFE" men även det bör väl ha samma problem med synkron vs asynkron kod?

Någon riktig JS-kodare får gärna inflika!

Mvh,
WKL.

Visa signatur

"Den säkraste koden är den som aldrig skrivs"

Permalänk

Jag tror tyvärr inte ditt förslag kommer fungera heller, som du misstänker..
Jag är rädd för att jag behöver tänka rejält "out of the box" här och hitta nån typ av workaround.. Men nån får gärna bevisa motsatsen.

Visa signatur

Dator: MB: Gigabyte Z390 M GAMING mATX | CPU: Intel Core i9 9900K 3.6 GHz (Haswell) | RAM: Corsair 16GB (KIT) 3200Mhz Vengeance LPX | Grafikkort: ASUS GeForce RTX 3060 12GB PHOENIX V2 (LHR) | Chassi: Fractal Design Mini | PSU: Corsair RM750X 750W v2 | Optisk: ASUS BW-12B1ST Blu-Ray/DVD brännare | CPU-kylare: Noctua NH-U12S | Operativ: Windows 11 | Scanner: Canon Canoscan 9000F
Övrigt: Nintendo Switch, NES Mini, SNES Mini, Nintendo New 3DS, NES, Famicom AV, Famicom Disk System, PS3, PS5, AppleTV 4K, Synology NAS DS923+ (32GB), iPhone 14 Pro 128GB, LG OLED 55C2,

Permalänk
Medlem
Skrivet av oRBIT2002:

Jag tror tyvärr inte ditt förslag kommer fungera heller, som du misstänker..
Jag är rädd för att jag behöver tänka rejält "out of the box" här och hitta nån typ av workaround.. Men nån får gärna bevisa motsatsen.

Hur ser din AJAX-funktion ut? Svårt att peka på vad som blir fel eller ge förslag på förändringar utan att veta vad du testat.

Visa signatur

AMD Ryzen 7 1700X 3.8 GHz 20MB | ASUS PRIME X370-PRO | MSI GeForce GTX 1080 Gaming X 8GB | G.Skill 16GB DDR4 3200 MHz CL14 Flare X | Corsair RM650x 650W

Permalänk

Min kod är dessvärre en enda röra nu när jag experimenterar.. Ajax-anropet ser i dagsläget snarlikt ut det enligt nedan. Jag vill ha ut svaret från den till den anropande funktionen, ValidateForm().
$.ajax({
type: "POST",
data: cmd,
url: "/api/xxxx",
success: function (isValid) {
return isValid;
}
});

Visa signatur

Dator: MB: Gigabyte Z390 M GAMING mATX | CPU: Intel Core i9 9900K 3.6 GHz (Haswell) | RAM: Corsair 16GB (KIT) 3200Mhz Vengeance LPX | Grafikkort: ASUS GeForce RTX 3060 12GB PHOENIX V2 (LHR) | Chassi: Fractal Design Mini | PSU: Corsair RM750X 750W v2 | Optisk: ASUS BW-12B1ST Blu-Ray/DVD brännare | CPU-kylare: Noctua NH-U12S | Operativ: Windows 11 | Scanner: Canon Canoscan 9000F
Övrigt: Nintendo Switch, NES Mini, SNES Mini, Nintendo New 3DS, NES, Famicom AV, Famicom Disk System, PS3, PS5, AppleTV 4K, Synology NAS DS923+ (32GB), iPhone 14 Pro 128GB, LG OLED 55C2,

Permalänk
Medlem
Skrivet av oRBIT2002:

Min kod är dessvärre en enda röra nu när jag experimenterar.. Ajax-anropet ser i dagsläget snarlikt ut det enligt nedan. Jag vill ha ut svaret från den till den anropande funktionen, ValidateForm().
$.ajax({
type: "POST",
data: cmd,
url: "/api/xxxx",
success: function (isValid) {
return isValid;
}
});

Testa att definiera isValid utanför ajax-anropet, sätt sedan dess värde till true inuti success och returnera det sista du gör i den omslutande funktionen.

const ValidateForm() { let isValid = false; $.ajax({ type: "POST", data: cmd, url: "/api/xxxx", success: function () { isValid = true; } }); return isValid; }

Visa signatur

AMD Ryzen 7 1700X 3.8 GHz 20MB | ASUS PRIME X370-PRO | MSI GeForce GTX 1080 Gaming X 8GB | G.Skill 16GB DDR4 3200 MHz CL14 Flare X | Corsair RM650x 650W

Permalänk
Skrivet av noMad17:

Testa att definiera isValid utanför ajax-anropet, sätt sedan dess värde till true inuti success och returnera det sista du gör i den omslutande funktionen.

const ValidateForm() { let isValid = false; $.ajax({ type: "POST", data: cmd, url: "/api/xxxx", success: function () { isValid = true; } }); return isValid; }

Kommer inte return isValid i slutet på ValidateForm() att hinna köras innan $.ajax() hinner slutföra sitt dock?

Mvh,
WKL.

Visa signatur

"Den säkraste koden är den som aldrig skrivs"

Permalänk
Medlem
Skrivet av WebbkodsLärlingen:

Kommer inte return isValid i slutet på ValidateForm() att hinna köras innan $.ajax() hinner slutföra sitt dock?

Mvh,
WKL.

Det var länge sedan jag använde jQuery så jag minns inte exakt hur det fungerar och har inte testat det själv, men dokumentationen säger följande angående async:

Citat:

As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done().

Eftersom att OP returnerade inifrån success men inte den omslutande funktionen så tänkte jag att det var värt att testa. Men det kan mycket väl vara som du säger.

Visa signatur

AMD Ryzen 7 1700X 3.8 GHz 20MB | ASUS PRIME X370-PRO | MSI GeForce GTX 1080 Gaming X 8GB | G.Skill 16GB DDR4 3200 MHz CL14 Flare X | Corsair RM650x 650W

Permalänk

Kan gärna diskutera fram eventuella lösningar men jag tycker själva infallsvinkeln känns konstig. Hela grejen med AJAX är väl att det ska vara asynkront. 😁 Det är en del av namnet tillochmed. Det borde inte vara ett problem om du gör saker på rätt sätt. Vad är det för slags validering som ska göras gällande formuläret?

Sedan ska du eventuellt returnera ett post-anrop som är "successful" men ändå inte valid? Låter lite märkligt det också kan jag tycka. Men har du mer kod att visa oss så kanske det ger en ökad förståelse.

Permalänk

Mitt förslag är att du kör koden för valideringen innan du gör själva anropet från AJAX. Det finns inbyggd funktionalitet för detta och det är nog så du bör hantera detta.

Googla lite kring detta
https://jqueryvalidation.org/validate/#submithandler

"The right place to submit a form via Ajax after it is validated."

Permalänk

Jag fick fart på detta tillslut. Jag fick skriva om en del befintlig gammal kod som jag egentligen inte ville röra men så blev det. Lite async/await fixade biffen. Tack till alla för engagemanget.

Visa signatur

Dator: MB: Gigabyte Z390 M GAMING mATX | CPU: Intel Core i9 9900K 3.6 GHz (Haswell) | RAM: Corsair 16GB (KIT) 3200Mhz Vengeance LPX | Grafikkort: ASUS GeForce RTX 3060 12GB PHOENIX V2 (LHR) | Chassi: Fractal Design Mini | PSU: Corsair RM750X 750W v2 | Optisk: ASUS BW-12B1ST Blu-Ray/DVD brännare | CPU-kylare: Noctua NH-U12S | Operativ: Windows 11 | Scanner: Canon Canoscan 9000F
Övrigt: Nintendo Switch, NES Mini, SNES Mini, Nintendo New 3DS, NES, Famicom AV, Famicom Disk System, PS3, PS5, AppleTV 4K, Synology NAS DS923+ (32GB), iPhone 14 Pro 128GB, LG OLED 55C2,