Empty response from DB handling

c
angular
javascript

(Andrei Luca) #1

Salut
Daca faceti un request care cere date din baza de date iar raspunsul este gol, care este modul ideal de a trata aceasta situatie?
Trimiteti inapoi catre frontend un Ok() fara payload? BadRequest()? Alt cod HTTP?

Cum rezolvati situatia asta in frontend? Verificati daca payload.length !=0 sau va folositi de codul HTTP trimis din backend?
Pe scurt, situatia mea e urmatoarea :

  • Am un dropdown cu multiselect. In functie de itemii selectati de user fac request in baza de date.
  • Daca userul deselecteaza toti itemii din dropdown ar trebui sa ii afisez un mesaj pe ecran sa-i spun “no data, w/e”. Daca userul are ceva selectat ii returnez valorile din DB.
  • In frontend eu fac urmatorul lucru: responseData.json(). Daca responseData != [], functioneaza ok. Daca responseData == [] atunci responseData.json() arunca “Unexpected end of JSON input”

Si caut pe net cum sa tratez situatia asta. Fie trimit din backend altceva decat Ok() cu un array gol, fie trimit Ok() cu un array gol si fac verificari in frontend sa vad daca responseData are ceva inauntru sau nu.

Scuze pentru mesajul lung. Sunt sigur ca se putea scrie si mai succint de-atat.
Mentionez ca folosesc C# pe backend, Angular 5 pe frontend.


(Alexandru Tudor) #2

Eu trimit Ok cu obiectul gol, iar verificarea ramane pentru partea de front, cat de “elegant” o cosmetizezi tu, ce mesaj afisezi in locul erorii. Tot C# cu Angular 5 :smiley:


(Georgiana Gligor) #3

trimite un valid json, de ex {}, pt ca [] nu e json


(cosmos) #4

Poti sa returnezi asta

return Json(new EmptyResult());
Merge si pt asp .net core

De aici


(Alex) #5

presupunand ca vrei rezultatele din db exact asa cum vin, nu inteleg ce are json_encode((array)$results)? de ce trebuie sa verifici daca ai sau n-ai rezultate din backend si sa intorci alt tip de raspuns in functie de rezultate.

@tekkie, [] e valid. o sa ai un array gol daca-l decodezi.

PS: nu observasem ca folosesti c#. dar cred ca poti verifica daca ai rezultate din db si sa trimti un array gol in caz ca n-ai.


(Andrei Avram) #6

E valid, dar nu pentru toata lumea. Pe Java/Android am vazut la un moment dat pe cineva ca nu se descurca.


(Georgiana Gligor) #7

Ok, ES5 zice ca poti avea array gol. Dar mai sap un pic daca am timp, pt ca nu sunt convinsa ca e respectata specificatia.

@Andrei_Luca cand spui responseData.json() ce tip de obiect este responseData?

Pe de alta parte angular in sine pare sa aiba probleme cu empty body si suspectez ca trebuie testat mai atent sa nu cumva sa fie acest scenariu.


(Horia Coman) #8

Un array că raspuns e ok, la fel că și un număr, boolean sau string. In principiu sunt obiecte JSON valide.

Sunt câteva motive pentru care nu vrei decât obiecte că răspuns tho’:

  • Un obiect îți permite să adaugi și alte date la răspuns. Poate vrei o descriere a erorii de exemplu. Daca nu acum, poate intrun an. E greu sa schimbi API-uri deja folosite așa că un obiect e soluția cea mai OK că să-ți faci viață ușoară.
  • Erau la un moment dat diverse metode de code injection bazate pe suprascrierea constructorului Array. Mai multe detalii aici. Nu cred că sunt relevante acum, dar e ceva ce browserul trebuie să prevină.

(Alex) #9

ceva de genul {baz:…,foo:…,payload:[]/{}}. dar vad ca el scuipa direct rezultatele din db.
daca folosea un raspuns mai standardizat ii era mai usor sa verifice daca are sau n-are rezultate.

ps:
http://jsonapi.org/examples/


(Andrei Luca) #10

Mersi pentru raspunsuri.
Pana la urma am ales sa raspund din backend cu NoContent() -> care are http status code 204 (“The server successfully processed the request and is not returning any content”). Am presupus eu ca e cel mai potrivit in cazul de fata.

@tekkie mersi de issue-ul cu empty body din angular. Ce-i drept, eu dezvoltarea o fac doar pe Chrome. O sa testez azi si pe IE11 sa vad daca ce am facut eu functioneaza. responseData e de tipul Response din Angular. care extinde Body. care are o metoda json() care zice ceva de genul asta : “This is not Angular’s own design. The Angular HTTP client follows the Fetch specification for the response object returned by the Fetch function. That spec defines a json() method that parses the response body into a JavaScript object.”

@alescx la ce te referi prin raspuns mai standardizat?

Pe mine mai mult ma interesa de fapt care e best practice in cazul asta. Cand stii deja din frontend ca n-o sa ai rezultate in baza de date din cauza ca user-ul nu a selectat nimic, rezolvi situatia direct din frontend, sau lasi sa se duca requestul si sa se intoarca cu un raspuns gol ca sa pastrezi componenta cat mai dumb?
Mentionez aici ca folosesc si ngrx/store (inspired pe Redux pentru cine e familiar) si incerc sa pastrez lucrurile cat mai straight-forward. Incerc sa nu adaug logica daca nu e nevoie.


(Andrei Luca) #11

Desi acum ca ma gandesc mai bine, mai degraba as folosi Ok() (http status code 200) care n-are niciun obiect inauntru. Aia e…ai cerut, a venit un raspuns ok, rezultatele sunt 0 randuri. Si de-aici sa afisez eu un mesaj in componenta daca rows.length === 0. (raspunsul asta a depasit cumva scopul intrebarii. dar poate ajuta pe cineva pe viitor)


(cosmos) #12

Abordarea asta este mai buna decat cea cu 204 :slight_smile:

Cel putin asa am vazut dupa ce am facut si eu o cautare ieri.
Daca nu am rezultat la dropdown multiselect, eu afisez un mesaj “nothing found” sau ceva de genul.
Este bine ca ai rezolvat.


(Andrei Luca) #13

Dupa ce am citit bug-ul de pe github pus de @tekkie am vazut ca este o problema in Angular.
Unul din work-around-uri era ce fel facusem eu initial, sa raspund cu 204.
Am ales sa raspund cu o lista goala : Ok(new List());
Pana cand se va fixa in Angular las asa.

Gracias !


(Alex) #14

in principiu la json api

sau macar sa fii consistent in raspunsuri. daca astepti un array o sa trimiti mereu un array, chiar daca-i gol.te scuteste de verificari in plus