greevesh's avatar

Trying to Retrieve Corresponding Product Data When Clicking on Product

I'm building a videogame store. I have my 4 categories (playstation, xbox, nintendo, pc). Each category view and controller retrieves the product details from a MySQL database. On each category page, 12 products are retrieved with their corresponding name, image and price. Here is the logic that enables this functionality (just for context, this isn't what I want to do with the other pages):

// playstation.blade.php

@section('content')
    @if(isset($playstationGames))
        @foreach($playstationGames as $playstationGame)
            <h2>{{ $playstationGame->name }}</h2>
            <a href="{{ $playstationGame->slug }}"><img src="{{ asset($playstationGame->image) }}" alt="playstationgame"></a>
            <h4>{{ $playstationGame->price }}</h4>
        @endforeach 
    @endif
@endsection

// PlaystationController.php

public function index()
    {   
        $playstationGames = Game::find([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);

        return view('products.playstation')->with([
            'playstationGames' => $playstationGames
        ]);
    } 

When I click on one of the images, I want to be directed to a page for that product. For example, if I click on the image for Mario Kart, I want to be directed to a page with the data for that game (corresponding image, name, price, description). These details are already in the database. I know how to fetch these as an array. But I want to fetch these individually and for each one to correspond to the page (slug) I'm visiting.

How can I achieve this?

Edit: Here's an example of what I want: https://laravelecommerceexample.ca/shop

When you click on the image for 'laptop 1', you are taken to it's corresponding 'slug page' (I've already achieved this). What I don't know how to do is return the unique description, price, image etc as displayed when you click on the product image on this website. All I've managed to do is return my blade template from my slug link.

As you can see in the above code. I know how to loop through the products and return them all. I don't know how to return one that matches the corresponding slug of the page.

Thanks

0 likes
16 replies
jlrdw's avatar

Have you ever made an image a link, that would be step one finding a small tutorial on doing that.

also if this is a real professional site, I highly suggest one of two things, 1 actually find a good well maintained shopping cart on GitHub and use it or at least view the code on some of them and learn how things work by a study of the code.

Just a suggestion.

But you just use the image as a link no different than like in edit page, just use a route and find the data in the controller really no different than in edit page but you're just using the image instead of a edit or view link button.

greevesh's avatar

@jlrdw

Yes, I have made an image a link. All the images in this app are links.

The goal is to retrieve the corresponding data for the product from the db. The pages are fine. The issue isn't with links. The issue is that I don't know how to retrieve the corresponding data for each product. Each page that extends game.blade.php when clicking on a product image should return me the product details.

Maybe I complicated my query by talking about the 'add to cart' functionality. I'll see if I can improve it.

Thanks

Snapey's avatar

You need a route in your web.php file that can accept the slug and sends to a controller show method.

This show method retrieves the model mentioned in the slug and passes it to a view for display.

This base level of functionality should be covered in the Laravel from scratch video series. I suggest you watch this first.

(lessons completed = 0)

greevesh's avatar

That's not the problem. I'm having no trouble displaying my view from my controller. I already have this code here:

// web.php

Route::get('/playstation/{slug}', 'PlaystationController@show');

// PlaystationController.php

public function show($slug)
    {   
        return view('products.game');
    }

I just want to know how I can retrieve my product details from the database on each 'slug' page. So, when I click on the game 'Alien Isolation', it already takes me to correct page. What it doesn't do is return me the details I want (price, description, image). I've edited my post again and provided a real life example.

Sinnbeck's avatar

So something like this?

public function show($slug)
    {   
        $game = Game::where('slug', $slug)->first();
        return view('products.game', ['game' => $game]);
    }
greevesh's avatar

@sinnbeck Something like this. But this specifically isn't returning my data. It isn't causing an error either though.

Sinnbeck's avatar

What do you get if you do this

public function show($slug)
    {   
        $game = Game::where('slug', $slug)->first();
    dd($game);
        return view('products.game', ['game' => $game]);
    }
greevesh's avatar

@sinnbeck I get the word 'null' in orange font with a black rectangular background.

Sinnbeck's avatar

That means that there isn't any games with that slug in the database :)

greevesh's avatar

@sinnbeck But there are. The slug in the database is what's used to get me to that page in the first place. I'm confused.

I also tried this as I know there are games in the db where platform = playstation:

public function show($slug)
    {   
        $game = Game::where('platform', 'playstation')->first();
        dd($game);
        return view('products.game', ['game' => $game]);
    }

This will return the first game that's in the database that has platform = playstation. Makes sense. But when I remove the dd function, no data returns.

Sinnbeck's avatar

Ok try dd($slug). Do you get the expected slug?

greevesh's avatar

@sinnbeck Yes I do. I get the expected slug.

I realised earlier I wasn't even passing data from the controller to the view (doh!).

That code you gave me should work because I've been successful with something similar before.

Right now, I'm able to retrieve the data I need, but only for one game and it's fetched for whatever page I'm on. So, I have the data rendered for Alien Isolation but for Mario Kart the Alien Isolation details still appear. As Alien Isolation is the first game in the database. This is the code I'm using:

// PlaystationController.php

public function show($slug)
    {   
        $game = Game::where('platform', 'playstation')->firstOrFail();
    
        return view('products.game', ['game' => $game]);
    }

// game.blade.php

@extends('layouts.app')

@section('content')
    <div class="container">
        <h2>{{ $game->name }}</h2>
        <img src="{{ asset($game->image) }}" alt="game">
        <h4>{{ $game->price }}</h4>
        <p>{{ $game->description }}</p>
    </div>
    <button type="button" class="btn btn-secondary btn-lg">Add to Cart</button>
@endsection

Of course, to fix this I've tried using this so the slug in URL get request matches the slug in the database:

// PlaystationController.php

public function show($slug)
    {   
        $game = Game::where('slug', $slug)->first();
        
        return view('products.game', ['game' => $game]);
    }

And I get this error Trying to get property 'name' of non-object

This is where I'm up to now.

Jaytee's avatar

I have this project i've just published on Github, as I figured it's time to share my old work. My situation was slightly different as I wasn't aiming to sell games, I was aiming to provide tournament services.

Nevertheless, some of the code in the repository may be of relevance to you in the future, and how I first started out when building applications like this.

You can find it here: https://github.com/JayteeNZ/esports-archived

greevesh's avatar

I thought I solved my problem. Here's how I thought I fixed it:

Instead of:

Game::create([
            'slug' => 'playstation/alien-isolation',
            'platform' => 'playstation',
            'name' => 'Alien Isolation', 
            'price' => '£19.99', 
            'description' => 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Nesciunt debitis, amet magnam accusamus nisi distinctio eveniet ullam. Facere, cumque architecto.',
            'image' => '/storage/images/playstation/alien_isolation.jpeg'
        ]);

I used the slug method:

Game::create([
            'slug' => Str::slug('Alien Isolation', '-'),
            'platform' => 'playstation',
            'name' => 'Alien Isolation', 
            'price' => '£19.99', 
            'description' => 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Nesciunt debitis, amet magnam accusamus nisi distinctio eveniet ullam. Facere, cumque architecto.',
            'image' => '/storage/images/playstation/alien_isolation.jpeg'
        ]);

This worked while I had this in my controller:

public function show($slug)
    {   
        $game = Game::where('slug', $slug)->first();
    
        return view('products.game')->with([
            'game' => $game
        ]);
    }

and this in my web.php:

Route::get('/playstation/{slug}', 'PlaystationController@show');

By 'worked', I mean it returned the data according to the corresponding slug of the page and the slug in the database. Unfortunately, as soon as I refresh the page, I get a 404.

This makes absolutely no sense to me but I am new to this.

I also don't understand how this can possibly work at all when I run my data dump method and get a response of 'null':

$game = Game::where('slug', $slug)->first();
dd($game);

Why would I be getting a 404 but only after refreshing the page? There are so many things I'm confused about here. Does anyone know why this may be?

Thanks

Please or to participate in this conversation.