Angular 6 и php: httpclient не отправляет массивы на сервер даже при использовании добавления в httpparams

Мне нужно отправить массив данных, используя HttpClient из Angular 6, на сервер PHP.

У меня есть выпадающий список, из которого я выбрал и вставил в массив:

arrayOfLegalProtection=[];
addSit(){
    let l_id = '';
    let p_id = '';
    let s_id = '';
    let add_date = '';
    l_id = this.formGroup.controls['l_id'].value;

    p_id = this.formGroup.controls['p_id'].value;
    s_id = this.formGroup.controls['s_id'].value;
    add_date = this.formGroup.controls['add_date'].value;
    this.showSubHeader++;
    this.arrayOfLegalProtection.push({lId: l_id, 
      pId: p_id,
      sId: s_id, 
      addDate: add_date})
    console.log(this.arrayOfLegalProtection);
}

Результат консоли показывает мне правильные введенные значения:

[{"lId":"1","prId":"1","sId":"2","addDate":"2018-09-14"},

{"lId":"","pId":"1","sId":"5","addDate":"2018-09-14"},

{"lId":"","pId":"2","sId":"","addDate":"2018-09-20"}]

Теперь мне нужно добавить этот массив в метод httpclient post и отправить его на сервер, но, как сказано в обсуждении этого поста, массивы нельзя отправлять через библиотеку angular HttpClient.

Нам нужно использовать append, или JSON.stringify(), или .append().

Я опубликовал вопрос после использования метода JSON.stringify() и, как вы можете видеть, были ошибки. И даже echo count($array) всегда является 1, даже если многомерный массив содержит 0 или N строк данных.

Поэтому я переключился на другой метод с использованием .append():

saveUnitData(unit_type, 
    location_type_id, user_id, number_of_hh, unit_status, add_date, arrayOfActualities)
  { 
    console.log(user_id);
    let httpParam = new HttpParams().set('unit_type', unit_type)
                                      .set('location_type_id', location_type_id)
                                      .set('user_id', user_id)
                                      .set('number_of_hh', number_of_hh)
                                      .set('unit_status',unit_status)
                                      .set('add_date', add_date);
    Object.keys(arrayOfActualities).forEach(key=>{
      httpParam = httpParam.append('arrayOfActualities', arrayOfActualities);
    })
                                      //.set('arrayOfActualities', arrayOfActualities);
    let headerOptions = new HttpHeaders();
    headerOptions.append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    console.log('h'+arrayOfActualities);
    return this.http.post(this.globalVar.UnitSavedataUrl, httpParam, {headers: headerOptions});
  }

Используя этот код:

Object.keys(arrayOfActualities).forEach(key=>{
          httpParam = httpParam.append('arrayOfActualities', arrayOfActualities);

Я попытался преобразовать объект в массив с помощью добавления, чтобы его можно было отправить через службу httpClient.

В заголовке запроса мы видим обычные отправленные данные, но массив повторяется сотни и сотни раз.

enter image description here

И ответ от сервера всегда:

C:\wamp64\www\dev\UnitSaveData.php:23:string '[{"legalId":"","protectionId":"","situationId":"","addDate":"2018-09-14"},{"legalId":"","protectionId":"","situationId":"","addDate":"2018-09-14"}]' (length=147)

Но в базу ничего не добавили.

Обратите внимание, что сценарий PHP аналогичен сценарию предыдущий пост без ответа.

У меня никогда не было проблемы с отправкой массивов в API с HttpClient. Почтовые запросы имеют body, куда вы можете отправить практически любой объект js. Параметры Http - это параметры, которые добавляются к вашему URL-адресу: если вы используете почтовые запросы, они вам не нужны.

user4676340 10.09.2018 09:37

Кстати, HttpHeaders неизменяемый, поэтому вам нужно сделать это: let headerOptions = new HttpHeaders().append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');

David 10.09.2018 09:40

@trichetriche, пожалуйста, проверьте ссылку на github, добавленную в мой пост, и прочтите о проблеме отправки массивов с помощью httpClients. Если вы правы, возможно, у меня проблема со сборкой массива, поэтому я добавил метод проталкивания в массив.

alim1990 10.09.2018 09:58

@david да он уже добавлен.

alim1990 10.09.2018 09:58

@droidnation, как было сказано ранее, нет проблем с отправкой массивов по почте. Если у вас возникла проблема, предоставьте минимальный воспроизводимый пример с ее воспроизведением.

user4676340 10.09.2018 10:05

@trichetriche да, но со стороны сервера он не читается, вот в чем проблема.

alim1990 10.09.2018 10:15

Тогда ваша проблема не в Angular, а в вашем API, поскольку никакой код Angular не может решить эту проблему (даже если вы используете код Angular, проблема связана с PHP). Чтобы не загрязнять теги, я удаляю теги Angular. Если вы считаете, что это неоправданно, объясните, почему.

user4676340 10.09.2018 10:17

Ваш PHP-скрипт вызывает json_encode(), который создает строку JSON. Если вы намерены преобразовать JSON в массив, выполните json_decode(). Однако прежде всего убедитесь, что все, что вы передаете в json_decode(), еще не является массивом.

B. Fleming 10.09.2018 10:24

Уважаемый @trichetriche, я нашел решение, и это была смешанная ошибка как в angular, так и в PHP-скрипте, пожалуйста, верните теги, чтобы я мог ответить на свой вопрос.

alim1990 10.09.2018 10:34

@ B.Открытие вашего комментария - это часть решения. Спасибо.

alim1990 10.09.2018 10:35

Добавление или удаление тегов не имеет отношения к публикации ответа (и вы можете сделать это сами, если не знали). Читая ответ @B.Fleming, я думаю, что вы должны вместо этого проголосовать за ответ, который он предоставит, поскольку он заслужил некоторую репутацию за то, что вел вас в правильном направлении.

user4676340 10.09.2018 10:37

@trichetriche Я только намекнул на возможную причину проблемы. Это было скорее указанием в правильном общем направлении, чем ответом. Для этого мне не нужна репутация. Однако, спасибо!

B. Fleming 10.09.2018 21:06
0
12
759
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нашел решение.

Да, HttpClient() принимает массив как HttpParams().

Для скрипта Angular, я делал следующее:

let httpParam = new HttpParams().set('unit_type', unit_type)
   .set('location_type_id', location_type_id)
   .set('user_id', user_id)
   .set('number_of_hh', number_of_hh)
   .set('unit_status',unit_status)
   .set('add_date', add_date)
   .set('arrayOfActualities', arrayOfActualities); 

Как упоминалось в документации HttpParams(), .set() принимает значение как строку, которая сбивает с толку скрипт на стороне сервера даже при использовании json_encode().

Итак, решение заключалось в том, чтобы добавить к arrayOfActualities массив:

let httpParam = new HttpParams().set('unit_type', unit_type)
    .set('location_type_id', location_type_id)
    .set('user_id', user_id)
    .set('number_of_hh', number_of_hh)
    .set('unit_status',unit_status)
    .set('add_date', add_date)
    .set('arrayOfActualities', arrayOfActualities);

httpParam.append('arrayOfActualities', JSON.stringify(arrayOfActualities));

На стороне PHP мне нужно использовать json_decode($arr, true), чтобы позволить сценарию сервера выполнять итерацию по массиву, поскольку итерация по массиву json создавала для меня проблему, поскольку он не мог читать заголовки полей из-за двойных кавычек:

$arr = json_decode($arrayOfActualities, true);
if(count($arr)>0)
  {
     foreach($arr as $array)
     {

     }
  }

...

Как сказал @B.Fleming:

Your PHP script is calling json_encode(), which produces a JSON string. If your intent is to transform JSON into an array, do json_decode(). Before anything, though, ensure that whatever you're passing into json_decode() is not already an array.

Другие вопросы по теме