I need to store my contacts table data which I get through user input like below array:
0 => array:5 [▶]
1 => array:5 [▼
0 => "John Doe"
1 => "[email protected]"
2 => "15551-234567"
3 => "New York, NY"
4 => "230"
]
2 => array:5 [▼
0 => "Jane Smith"
1 => "[email protected]"
2 => "15552345678"
3 => "Los Angeles, CA"
4 => "5201"
]
3 => array:5 [▼
0 => "Robert Johnson"
1 => "[email protected]"
2 => "8.80156E+13"
3 => "Chicago, IL"
4 => "4110"
]
4 => array:5 [▶]
5 => array:5 [▶]
6 => array:5 [▶]
7 => array:5 [▶]
8 => array:5 [▶]
]
And I have anther input tag which I need to index the previous array to store in my contacts table.
0 => "contact_name"
1 => "Select Schema"
2 => "contact_number"
3 => "Select Schema"
4 => "Select Schema"
]
I have used following lines of codes to index it and store it into database. But the problem is I got only first index data of every row.
Means if my tag array input comes contact_name , contact_number I need to get the $contactToBeInserted
array as below:
0 => array:2 [▼
"contact_name" => "John Doe"
"contact_number" => "15551-234567"
]
1 => array:2 [▼
"contact_name" => "Jane Smith"
"contact_number" => "15552345678"
]
But I only get contact_name in $contactToBeInserted
array.
0 => array:1 [▼
"contact_name" => "john doe"
]
1 => array:1 [▼
"contact_name" => "Robert"
]
Why’s that? Is there any efficient way to indexing the data and get the exact output I want?
public function saveReviewData(Request $request)
{
$allowedTags = ['contact_name','contact_email','contact_number','contact_location'];
$contactToBeInserted = [];
foreach($request->tag as $tagIndex => $tag)
{
if (!in_array($tag, $allowedTags))
{
continue;
}
foreach(array_slice($request->data, 1) as $index => $contactData)
{
$contactToBeInserted[$index][$tag] = $contactData[$tagIndex];
$this->validate($request, [
'contact_number' => [
Rule::unique('contacts')->where(function ($query) {
$query->where('user_id', '=', Auth::user()->id);
})
],
]);
$contact = new Contact();
$contact->contact_name = $contactToBeInserted[$index]['contact_name'] ;
$contact->contact_email = $contactToBeInserted[$index]['contact_email'] ;
$contact->contact_number = preg_replace('/[^0-9]+/', '', $contactToBeInserted[$index]['contact_number']);
$contact->contact_location = $contactToBeInserted[$index]['contact_location'];
$contact->user_id = Auth::user()->id;
$contact->save();
}
}
return redirect('contacts');
}
2
Answers
The problem is that you are using two nested loops, but you are only considering the outer loop index
$tagIndex
to access the data in the inner loop$contactData
. This results in overwriting the values.Use
array_combine
to usetags
as key and eachdata
as value.After that, to check if all tags are allowed, use
array_diff_key
. If there are no differences, insert into the array.To test my advice as native, runnable PHP, I’ve replaced some of the Laravel specific components with basic outputting.
It seems logical to me that your "$allowedTags" are actually "$requiredTags". Meaning if any of these fields are missing, then the request should not attempt to save the contact. For this reason, compare the incoming array of tags against the required tags; if not fully satisfied, do not process the data payload.
The next step is to iterate the rows in the data payload, and map the indexed values to the corresponding property names for each object to be saved.
Code: (Demo)
Making a request:
Output: