Angular i wysyłanie parametrów (json vs get)
Pracuję nad projektem Laravel (backend) i Angular (frontend) – niestety jeszcze na tym etapie nie tworzę frontu, po prostu nie znam się na Angularze tudzież jakimkolwiek innym framie frontowym, ale niebawem się to zmieni, bo postawiłem sobie za cel zostania fullstackiem.
Ok więc tak, problem był taki, że front wysyłał dane do backendu postem, przy czym dane były „serializowane” w pary: klucz=wartość&… taka płytka serializacja na poziomie angulara nie gwarantuje kodowania wartości, przez co wartości np z + czy & „popsują” nam string, i dane wyjściowe nie będą takie same jak dane wejściowe.
this.prepareParamsString = function(params) { var paramsStringArray = new Array(); for (property in params) { paramsStringArray.push(property + "="+ params[property]); } return paramsStringArray.join("&"); }
Rozwiązaniem dla tego problemu jest zamiana tablicy na format JSON, dzięki czemu zachowujemy oryginalość danych i po drugiej stronie możemy spokojnie odkodować dane do postaci tablicy (klucz = wartość)
Łatwo powiedzieć… napisać, ale w praktyce jest z tym więcej zabawy… dla osób, które nie mają doświadczenia i kombinują… :).
Otóż podczas wysyłania danych do Backendu, request był wysyłany z nagłówkiem:
Content-Type: application/x-www-form-urlencoded
Laravel z automatu odczytywał te dane jako jeden długi string i nie można było z tego zrobić tablicy, czyli próba pobrania danych:
$credentials = $request->all();
kończyła się niepowodzeniem… po prostu otrzymywałem pusty string.
Na stackoverflow znalazłem rozwiązanie, że dane wysyłane jsonem można odczytać poprzez:
json_decode(file_get_contents('php://input'), true);
Srsly??? Odczytywać Json takim wynalazkiem? Osobiście nie podoba mi się takie rozwiązanie, dlatego szukałem dalej…
Inne rozwiązaniem to:
$credentials = $request->json()->all();
Już lepiej, ale to oznaczałoby, że musiałbym w całym api zmienić wszystkie metody i być może nawet testy…- a wiadomo – lenistwo to częsta cecha nas programistów :).
Niemniej jednak, chciałem sprawdzić, jak czy testy przejdą – do testowania używam phpunit i teście do wysyłki danych widzę:
$this->json('POST', '/api/v1/auth/sign_in', [ 'email' => 'joe@boo.com', 'password' => '123456', ] )->seeJson(['success' => true]);
Dane są wysyłane w formacie JSON, i laravel korzysta ze standardowego $request->all()
, więc wina musi leżeć po stronie Angulara, który coś źle wysyła.. Co się okazało? Phpunit wysyłał requesta wykorzysttując nagłówki:
$headers = array_merge([ 'CONTENT_LENGTH' => mb_strlen($content, '8bit'), 'CONTENT_TYPE' => 'application/json', 'Accept' => 'application/json', ], $headers);
Angular korzystał z Content- Type: ” application / x- www-form-urlencoded” zmiana na Content – Type: ” application / json” zmieniło wszystko. Dane poprawnie się wysyłałmy, ja nie musiałem niczego w kodzie zmieniać i miałem pierwszy pomysł na wpis ;).
Tak więc {„Hello”: „World”} i dzięki za uwagę, mam nadzieję, że wpis komuś pomoże przynajmniej pomógł mnie 😀
Najnowsze komentarze