'JS sending array to php function but it gives array to string conversion error on implode

I have a fairly simple axios call going on within a vue component where I'm taking an array from the data and sending it via post URL to a php class that's trying to work with it. The current issue is that when it hits the php function, I'm getting an array to string conversion error, though I feel like the structure is correct within the data object in vue.

Tne php function is:

public function testStores( array $stores = null){
  $storeTest = empty($stores)   ?  ''  : "STORES:".implode(',',$stores). ";
}

Implode isn't working here due to the array to string issue, but I would expect $storeTest to give me "5, 10" in this case. Just a comma separated string made from the IDs.

What have I done wrong?

UPDATE: I'm dumping the array now, right before I call the implode function, and this is what prints:

array:2 [
  0 => array:1 [
    "id" => "5"
  ]
  1 => array:1 [
    "id" => "10"
  ]
]

var vm = 
new Vue({
  el: "#app",
  data: {
    stores: [
      {id: "5"},
      {id: "10"}
    ]
  },
  methods: {
    getStores(){
      
      axios({
        method: 'post',
        url: test,
        data: {
          stores: this.stores
        }
      }).then(function (response) {

      }).catch(function (error) {

      });
    }
  }
  
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button @click="getNames()">TEST</button>
</div>


Solution 1:[1]

You are sending a complicated structure through to the backend which you have to massage so that you can call implode on it. Here's how to massage it into a flat array.

<?php

// This is the data coming from the front end. 
$post = '{
   "stores":[
      {
         "id":"5"
      },
      {
         "id":"10"
      }
   ]
}';

// Decode it into an array
$input = json_decode($post, true);

// You now have an array that looks like this,

// Array
// (
//     [stores] => Array
//         (
//             [0] => Array
//                 (
//                     [id] => 5
//                 )
//             [1] => Array
//                 (
//                     [id] => 10
//                 )
//         )
// )

// Grab the sub-array from under `stores`.
$idList = $input['stores'];

// You now have an array that looks like this,
// Array
// (
//     [0] => Array
//         (
//             [id] => 5
//         )
//     [1] => Array
//         (
//             [id] => 10
//         )
// )


// You have to now flatten the array so that you have a single list of IDs like, [5, 10]
// You can use this, https://stackoverflow.com/a/8755001/296555
$flatArray = array_map('current', $idList);

// Now you can pass that to your function, 

function testStores( array $stores = null) {
  return empty($stores)   ?  ''  : "STORES:".implode(',',$stores);
}

echo testStores($flatArray);

As @ADyson points out, it would be better for the front end to pass a simple list to the backend. Try to get it to pass something like,

data: [5,10]

You can pass that directly to your function after json_decoding it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 waterloomatt