Nitish Kumar Nitish Kumar - 7 days ago 7
JSON Question

How to store data in array in loop

I'm trying to have data whose format should be something like this:

{"parent":
{"class":"Green","user_name":"Nitish","user_loc":"Delhi","user_id":1,"user_blockclass":null,
"child":[
{"class":"Green","user_name":null,"user_loc":null,"user_id":1,"user_blockclass":"fst",
"child":[
{"class":"Green","user_name":"pandey","user_loc":"sdgfsjd","user_id":6,"user_blockclass":"fst"},
{"class":"Green","user_name":"chaku","user_loc":"sdgjs","user_id":7,"user_blockclass":"snd"},
{"class":"Green","user_name":"iks","user_loc":"sjkdfhkjs","user_id":8,"user_blockclass":"trd"},
{"class":"Green","user_name":"yash","user_loc":"hfksjdhfk","user_id":9,"user_blockclass":"frt"},
{"class":"Green","user_name":"joshi","user_loc":"dsfh","user_id":10,"user_blockclass":"fth"}
]},
{"class":"Green","user_name":null,"user_loc":null,"user_id":1,"user_blockclass":"snd",
"child":[
{"class":"Green","user_name":"pandey","user_loc":"sdgfsjd","user_id":6,"user_blockclass":"fst"},
{"class":"Green","user_name":"chaku","user_loc":"sdgjs","user_id":7,"user_blockclass":"snd"},
{"class":"Green","user_name":"iks","user_loc":"sjkdfhkjs","user_id":8,"user_blockclass":"trd"},
{"class":"Green","user_name":"yash","user_loc":"hfksjdhfk","user_id":9,"user_blockclass":"frt"},
{"class":"Green","user_name":"joshi","user_loc":"dsfh","user_id":10,"user_blockclass":"fth"}
]},
]
}


Each element will contain 5 child elements and each child element will contain 5 child elements respectively. Now I'm trying to push data into array:

public function viewplans(Request $request)
{
$selectplan = $request->selectplan;
$user = Auth::user();
$userinfo= [];
$userinfo['class'] = "Green";
$userinfo['user_name'] = $user->name;
$userinfo['user_loc'] = $user->city;
$userinfo['user_id'] = $user->id;
if($selectplan == 1)
{
$blockclass = ['fst', 'snd', 'trd', 'frt', 'fth'];
$children = $user->relations()->wherePlanId($selectplan)->get();
$subuserinfo = [];
$subsubuserinfo = [];
for($i = 0; $i <5; $i++)
{

if($children[$i])
{
$subuser = User::findOrFail($children[$i]->pivot->child);
$subuserinfo['class'] = "Green";
$subuserinfo['user_name'] = $subuser->name;
$subuserinfo['user_loc'] = $subuser->city;
$subuserinfo['user_id'] = $subuser->id;
$subuserinfo['user_blockclass'] = $blockclass[$i];
$subchildren = $subuser->relations()->wherePlanId($selectplan)->get();
for($j = 0; $j < 5; $j++)
{

if($subchildren[$j]){
$subsubuser = User::findOrFail($subchildren[$j]->pivot->child);
$subsubuserinfo['class'] = "Green";
$subsubuserinfo['user_name'] = $subsubuser->name;
$subsubuserinfo['user_loc'] = $subsubuser->city;
$subsubuserinfo['user_id'] = $subsubuser->id;
$subsubuserinfo['user_blockclass'] = $blockclass[$j];
$subuserinfo['child'][$j] = $subsubuserinfo;
}
else
{
$subsubuserinfo['class'] = "Black";
$subsubuserinfo['user_name'] = 'No User';
$subsubuserinfo['user_loc'] = 'No Loc';
$subsubuserinfo['user_id'] = 'No ID';
$subsubuserinfo['user_blockclass'] = $blockclass[$j];
$subuserinfo['child'][$j] = $subsubuserinfo;
}
}
$userinfo['child'][$i] = $subuserinfo;
}
else
{
$subsubuserinfo['class'] = "Black";
$subsubuserinfo['user_name'] = 'No User';
$subsubuserinfo['user_loc'] = 'No Loc';
$subsubuserinfo['user_id'] = 'No ID';
$subsubuserinfo['user_blockclass'] = $blockclass[$i];
$userinfo['child'][$i] = $subuserinfo;
}
}
$tree = $userinfo;
// dd($tree);
return view('member.5matrix', [
'tree' => ($tree),
'blockclass' => $blockclass
]);
}
}


Even if the data is not available it should store the else value. Currently I'm getting error:


Undefined offset: 2


Help me out in having proper format of data as it is mentioned in JSON format.

Answer

The only places in the code you've shown that could be causing the "undefined offset: 2" error are

$subuser = User::findOrFail($children[$i]->pivot->child);

or

$subsubuser = User::findOrFail($subchildren[$j]->pivot->child);

Everywhere else that uses an integer ($i or $j) as an array key is either setting a value at that key, which won't cause an undefined offset error (it will just create the key if it doesn't exist), or referencing $blockclass, which has enough elements that your for loop won't exceed its length.

This means that for whatever reason, either

$children = $user->relations()->wherePlanId($selectplan)->get();

or

$subchildren = $subuser->relations()->wherePlanId($selectplan)->get();

isn't returning as many items as you're expecting it to. (More specifically, it seems it's only returning two items instead of five.)

There are probably other ways to do it, but if you want to keep doing it the way you are currently, you'll need to add checks that $children[$i] and $subchildren[$j] are set before you use them, and add your default values if they aren't.

if ($subuser) {... and if ($subsubuser) {... check that those variables are set, but you're actually getting the error at the time you're trying to set them. I think you could actually combine the findOrFail call with the check for $children[$i] and $subchildren[$j] inside the if condition:

if (isset($children[$i]) && $subuser = User::findOrFail($children[$i]->pivot->child)) {