Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

vincej's avatar
Level 15

How to Read Value Of Javascript Object

I have passed an array into an AJAX function from my controller. I now need to populate my view with the results of that array. Everything has been working fine up until now, however, I have recently changed the array into having 2 indices. Now I can not get the second index to render onto the view. I have tried Map() and Flatten() with no luck. I could be wrong in my assumption that I need an array with a single index, however I have also tried the simple object[1].value. So What am I missing here - this should be easy and obvious, when you know how!

Anyway here is the result of doing a console log on the data array of objects:

0: 		category_id: 60
			parent_id: "58"
			price: "100.00"
			product_id: "abc6798"
			product_name: "Install Rubber"

1: 		name: "Installation"
		parent_id: "57"

So - when I wish to pass this array to my view, I do this - it works fine with one index, but fails with 2 no matter what I do:

 response($.map(data, function (object) {
                            return {
                                label: object.product_name,
                                value: object.product_id,
                                price: object.price,
                                name:object[1].name,   		// Here is the problem
                            };
                        }));

select: function (event, ui) {
                $(' .product_name ').val(ui.item.label);
                $(' .price').val(ui.item.price);
                $(' .product_id ').val(ui.item.value);
                $(' .name').val(ui.item.name);       // Here is the problem again!
                return false;
            }

0 likes
30 replies
Snapey's avatar

access element [0] of your array?

vincej's avatar
Level 15

If you mean use name:object[0].name, and not 1 , then nope - doesn't work.

HI @tykus ... I'm back, and still can not solve yesterday's problem, but at least I'm inside the AJAX call now. Any ideas? Many thanks !

Snapey's avatar

You say you have two arrays. You need to get data from object[0] and object[1]

personally, not called object if it is an array

vincej's avatar
Level 15

@Snapey Not sure where I say, I have two arrays. I have one array with two indices.

jlrdw's avatar

@vincej looping json would be easier in an ajax return. I am on mobile, I will boot desktop.

Edit:

Something like:

                    for (var i = 0; i < data.length; i++)
                    {
                        var item = data[i];
                        alert(item.dogname);
                    }

Been a while as I use fetch js now. Just example.

A single item is no looping just direct data:

data.dogname
vincej's avatar
Level 15

@jlrdw Thanks for helping out! I don't really understand how your idea would solve things. My essential problem is that my array has two indices. I can pass the first index, but the second can not be read by JS. Would fetch solve my problem?

vincej's avatar
Level 15

My essential problem is that I have two queries. This results in me passing into my AJAX function an array with two indices. If I could consolidate my two queries into one then, all would be solved. I have tried and have not succeeded. Any ideas? Many thanks!

 public function product_prices($term)
    {
        $product = DB::table('products')
            ->join('categories','categories.category_id','=','products.category_id')
            ->select('product_id', 'price', 'products.product_name', 'products.category_id','categories.parent_id')
            ->where([
            ['product_name', 'LIKE', "$term" . '%'],
            ['products.status', '=', 'active'],
            ])
            ->get();

        $parent =  DB::table('categories')
            ->select('parent_id','name')
            ->where('category_id','=', $product[0]->parent_id )
            ->get();

    // This $productParent array is identical the the merged array below. How I am following what is given in the docs.  Dumb idea?? 
        $productParent = $product->merge($parent);  
        $result = $productParent->flatten()->unique();
        $merged = $result->all();

        echo json_encode($merged);
    }

vincej's avatar
Level 15

@jlrdw Thanks for that - very happy you are helping out. However, I have one array, not two. It is that my one array has two indices. So my map function reads the first index fine, and then it reads the second and it fails when it gets to name:object[1].name,

 response($.map(data, function (object) {
                            return {
                                label: object.product_name,
                                value: object.product_id,
                                price: object.price,
                                name:object[1].name,   		// Here is the problem
                            };
                        }));
jlrdw's avatar

@vincej make a data array, this was just done quick as an example:

    public function testg6()
    {
        $dogid = Request::input('somevar');
        $dog = Dog::select('dogname', 'comments', 'lastedit')
                ->where('dogid', '<', $dogid)
                ->get();
        $data['dog'] = $dog;
       // next line is just some made updata
        $data['mynumber'] = [['mydata' => 45], ['mydata2' => 100]];
        // you could add $data[something else here]...
        return Response::json($data);
    }


And use the proper keys to display as needed:

div.innerHTML += data['dog'][1].dogname;   // [1] is second row just example
div.innerHTML += data['mynumber'][1]['mydata2'];

One is "dog" another is "mynumber".

Treat each as needed.

The data array can hold many other arrays. And sorry edited the response.

Edit:

Just do more practice looping over json data in javascript. It's similar in jquery and fetch js. Sorry I don't understand the merging you are doing.

Snapey's avatar

you can't iterate over an array that has different attributes in each member

assign them to variables and do want you like with them

object0= object[0]
object1 = object[1]
Snapey's avatar

or replace this

$productParent = $product->merge($parent);  
        $result = $productParent->flatten()->unique();
        $merged = $result->all();

        echo json_encode($merged);

with

    return ['products' =>$products, 'parent'=>$parent];        //don't use echo, bad practice

or explain what format you want the data in, it's hard to tell from your code

rename $product to $products if it can return many items, also your php code will blow up if you don't get any products from the search. You get the category from product [0] only, why is that?

vincej's avatar
Level 15

@Snapey @jlrdw

Thank you both for your feedback.

@Snapey: Somewhere in the mists of time I learned that echo was the way to go. I will update all my code to use return.

Next, the query only returns a single product, not multiple. Your question: "You get the category from product [0] only, why is that?" I probably need to be clearer in how this code works:

The user enters a product term into a text field. JS Autocomplete calls Ajax which calls my Product controller. This controller searches for the details of this product plus it's relevant category details and then returns that data to the AJAX call. The AJAX function will now pass this data to the blade View.

The essential problem is that I have TWO arrays inside the AJAX call: Product and Parent. A single array works. I need to be able to send content from both arrays to the Blade view. So far, I have failed to find a solution to this:

 $.ajax({
                    url: "/product_prices/" + paramTrimed,
                    dataType: 'json',
                    success: function (data) {     // Two Arrays "product" and "parent"  enter here as "data"
                       
// THE BELOW RESPONSE AND SELECT FUNCTIONS IS WHERE THE PROBLEMS COME. I CAN NOT GET TWO ARRAYS TO BE RENDERED .  //  
                            response($.map(data, function (object) {
                            return {
                                label: object.product_name,
                                value: object.product_id,
                                price: object.price,
                                name:object[1].name,
                            };
                        }));
                    }
                });
            },

            select: function (event, ui) {
                $(' .product_name ').val(ui.item.label);
                $(' .price').val(ui.item.price);
                $(' .product_id ').val(ui.item.value);
                $(' .name').val(ui.item.name);
                return false;
            }

        });


jlrdw's avatar

@vincej like I showed above make an array of arrays:

$data['product'] = whatever array

and

$data['parent'] = another array you have

Then you pass $data in the response and you can work with $data anyway you need to.

You don't need to map anything.

Edit:

Also looking at the response in the network tab will clearly show how the data is "formed" thus how to access the data. In non ajax you see such things with a dd.

Snapey's avatar

HI @vincej

with respect, this code;

        $product = DB::table('products')
            ->join('categories','categories.category_id','=','products.category_id')
            ->select('product_id', 'price', 'products.product_name', 'products.category_id','categories.parent_id')
            ->where([
            ['product_name', 'LIKE', "$term" . '%'],
            ['products.status', '=', 'active'],
            ])
            ->get();

looks for all products that are like your term, so, potentially multiple records (or zero). This is reinforced by the fact that you use get() which will always return an array, even if the query only results in one match.

if you want a single record, use first() instead of get()

because you get an array, you then have to do this $product[0]->parent_id to get the ID from the first record without first checking that you actually have a record. Try typing an invalid search term and see what you get back from the ajax request!

Regarding the rest of the issue, did you try my suggestion?

vincej's avatar
Level 15

@jlrdw Thanks for that. I got the array created - obvious really. It comes through into Ajax looking like this:

data: 
		parent:Array(1)
				0: {parent_id: '1', name: 'Materials'}
	
		product: Array(1)
				0: {product_id: '123', price: '120.00', product_name: 'Harvest Shake', category_id: 54, parent_id: '53'}

I must be doing something very wrong as, when I try to console.log (data['parent'][0]{name}) It gives me an error on the name . It works up to the [0].

What am I doing wrong?

vincej's avatar
Level 15

@Snapey Hi Mark, Yes, you are 100% correct and I am totally wrong. This problem is sending me totally around the bend. I want the search term to pull as many matches as possible, so the user can select which ever one applies.

Did I try your suggestion? You mean replace :

$productParent = $product->merge($parent);  
        $result = $productParent->flatten()->unique();
        $merged = $result->all();

        echo json_encode($merged);

with

    return ['products' =>$products, 'parent'=>$parent];      

Yes, I have tried that and the two arrays come through nicely. However, just like @jlrdw suggestion I am struggling to get these arrays of objects "unpacked" into a string. Yours is a little different from jlrdw's

data: 
				parent: 	Array(1)
				0: {parent_id: '1', name: 'Materials'}

But like jlrdw's yours gives errors when I go beyond the [0] and try to get to the objects ie parent

console.log(data['parent'][0]);
vincej's avatar
Level 15

@snapey @jlrdw

BTW - I hate Javascript. I don't use it enough to be expert, but I use it ALOT. My goal is to go to Vue with Inertia, but for the moment I can not rewrite what I have and so I have to maintain and upgrade what I have got.

Just sayin'

vincej's avatar
Level 15

@Snapey So Many Thanks for all your help!!

I managed to get past this problem. Because Chrome Dev tools presents everything past the brackets with double braces, I assumed they were objects. NOPE. Wrapping things in more brackets made it work:

 console.log (data['product'][0]['product_name']);  // This works!

I am using your code as it is nice and clean. I have as recommended deleted all the merge stuff.

    return ['products' =>$products, 'parent'=>$parent];      

However, I still am having a problem getting these values past into the blade view.

I do not know why, but this does not work, except for the last "data['parent'][0]['name']" which does populate the view. All the ones with "data['PRODUCT'[0]['product_name']]" do not render. I have checked and triple checked the view classes, and they are all identical and correct.

						$('.product_name').val(data['product'[0]['product_name']]);
                        $('.price').val(data['product'[0]['product_price']]);
                        $('.product_id').val(data['product'[0]['product_id']]);
                        $('.name').val(data['parent'][0]['name']);

I have a theory that it has something to do with the JS autoComplete SELECT function which I was using before. I I tried it with one of the data arrays and it did not work. All this worked nicely when I only had a single array. This stuff drives me crazy.

 select: function (data) {                           
                $(' .product_name ').val(ui.item.data['product'[0]['product_name']]);  // DOES NOT WORK
                $(' .price').val(ui.item.price);
                $(' .product_id ').val(ui.item.value);
                $(' .name').val(ui.item.name);
                return false;
            }

jlrdw's avatar

@vincej also when one item you don't need the [0]

alert(data['parent']['name']);

So if I have:

    public function testg7()
    {
        $data['parent'] = [
            'parent_1d' => 1,
            'name' => 'Materials'
        ];
        $data['product'] = [
            'product_id' => '123',
            'price' => '120.00',
            'product_name' => 'Harvest Shake',
            'category_id' => 54,
            'parent_id' => '53'
        ];

        return Response::json($data);
    }

It would be:

                .then(function (response) {
                    if (response.status === 200) {
                        response.json().then(function (data) {
                            alert(data['parent']['name']);

                        });
                    }

I get:

Materials

Like I suggested, if you study what the network tab has, it will show how to transverse the data.

Also I suggest setting up several different types of json responses, and practice the different ways to display / loop over the data, that for many is the tricky part.

vincej's avatar
Level 15

@jlrdw Many Thanks for all your help!

I managed to get past this problem. Because chrome dev tools wraps everything in double braces { } after the [0] I assumed that these were objects. NOPE. Putting them into brackets made them render:

 console.log (data['product'][0]['product_name']);

With that bridge crossed, your suggestion and Snapey's are almost identical.

However, that said, I still am having a problem with getting these values now passed from the JS AutoComplete and Ajax function into the view. For reasons I do not understand the below does not render in the view, except for the very last one using "parent".

						$('.product_name').val(data['product'[0]['product_name']]);
                        $('.price').val(data['product'[0]['product_price']]);
                        $('.product_id').val(data['product'[0]['product_id']]);
                        $('.name').val(data['parent'][0]['name']);

I have a theory that it has something to do with JQuery AutoComplete function, and the use of this code which worked when I had one array.

jlrdw's avatar

@vincej is it a field, try:

$('#product_name').val(data['product'[0]['product_name']]);

Show the form.

Also what shows in the network tab for this data.

Edit:

I don't see how it's working with the [0]. When only one row of data you omit that key.

vincej's avatar
Level 15

@jlrdw I can't use an Id for the values as there are multiple rows. Hence a class.

Here is the body of the form where are the values are presented. All the classes, I think, are correct:

<tbody id="tableQuotation">
                        <tr class="quotation delete_row ">
                            <td>{{ Form::text('product_name[]',' ',['class'=>'form-control  product_name','placeholder'=>'Min. 2 characters']) }}</td>
                            <td> {{ Form::text('product_id[]',' ', ['class'=>'product_id form-control','readonly'=>'readonly' ]) }}</td>
                            <td>{{ Form::text('price[]',' ',['class'=>'form-control price','readonly'=>'readonly', ]) }}</td>
                            <td>{{ Form::text('quantity[]',' ', ['class'=>'form-control quantity ']) }}</td>
                            <td>{{ Form::text('cost[]',null ,['class'=>'form-control cost', 'readonly'=>'readonly' ]) }}</td>
                            <td>{{ Form::text('name[]',null ,['class'=>'form-control name', 'readonly'=>'readonly' ]) }}</td>
                            <td style="text-align: center">{{ Form::checkbox('delete','true') }}</td>
                            <td>{{Form::hidden("line_cost_hidden[]",' ',['class'=>'line_cost_hidden'])  }}</td>
                          {{--  <td>{{Form::hidden("materials_hidden[]",' ',['class'=>'materials_hidden'])  }}</td>--}}
                            <td>{{Form::hidden("services_hidden[]",' ',['class'=>'services_hidden'])  }}</td>
                            <div id="product_search"></div>
                        </tr>
                        </tbody>

Network tab: everything is good when a value is rendered inside a console log below . The network tab shows the name of the product and status 200.

 console.log (data['product'][0]['product_name']);

But I get nothing from the rest of the data values when placed into this structure except for the PARENT at the end. That does come through - it's a mystery!

						$('.product_name').val(data['product'[0]['product_name']]);
                        $('.price').val(data['product'[0]['product_price']]);
                        $('.product_id').val(data['product'[0]['product_id']]);
                        $('.name').val(data['parent'][0]['name']);
vincej's avatar
Level 15

@jlrdw because the form produces multiple rows dynamically using JS. Then when finished, the user submits.

Sinnbeck's avatar

@vincej I notice your brackets are placed in weird locations here

$('.product_name').val(data['product'[0]['product_name']]);
//think that should be
$('.product_name').val(data['product'][0]['product_name']);

//just to show it clearly
['product'[0]['product_name']] //before
['product'][0]['product_name'] //after
vincej's avatar
Level 15

@Sinnbeck BLOODY DAMN EFFING HELL!!!! :o) YOU FOUND IT ! THANK YOU !!!

All day long, @snapey @jlrdw and myself have been slaving away over this and there it was - simple damn syntax error in JS script!! And I did not get an error notification off PHPStorm because I turned them off, why?? because PHPStorm alerts over everything. UGH!

Having said that @snapey and @jlrdw did not waste their time - there was loads work done getting my Laravel code sorted out, for which I am ENORMOUSLY grateful.

All you guys are rockstars! Thank you does not go far enough. If we ever meet up - Beers on me!

Sinnbeck's avatar

@vincej Sometimes you just need another set of eyes :) Great that you got it solved

vincej's avatar
Level 15

@Sinnbeck Many Thanks to you ..... I think you solved it. Off to bed now ! Cheers !

Please or to participate in this conversation.