0

I'm using Laravel 7 with MySQL and Charts.js. I'm not sure how to echo/display the data of two columns ("player_name" and "kills") that's in my MySQL database in the JSON. Usually laravel has a @foreach loop that displays the data like so:

                @php
                  foreach($player_stats as $player) {
                  echo "['".$player->player_name."', ".$player->kills."],";
                  }
                @endphp

but I'm not sure how to use it inside the javascript/JSON. Please help? Here is the error I get and the rest of my code:

Error message:

Facade\Ignition\Exceptions\ViewException
Undefined variable: player_name (View: C:\wamp64\www\GeneralTesting\resources\views\show-players.blade.php)

PlayerController.php:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Player;

class PlayerController extends Controller
{
    public function playerstats() {
        $player_stats = Player::all();
        return view("show-players", compact("player_stats"));
    }
}

Route file (web.php):

Route::get("players", "PlayerController@playerStats");

View (show-players.blade.php):

<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Simple Sidebar - Start Bootstrap Template</title>

    <!-- Bootstrap core CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <!-- Custom styles for this template -->
    <link href="../assets/css/simple-sidebar.css" rel="stylesheet">

    <style type="text/css">


        #chart-container {
            width: 100%;
            height: auto;
        }
    </style>

    <!-- CHARTS MIS JS scripts -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js" integrity="sha256-R4pqcOYV8lt7snxMQO/HSbVCFRPMdrhAFMH+vr9giYI=" crossorigin="anonymous"></script>

<!--     <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.0-alpha1/js/bootstrap.bundle.min.js" integrity="sha256-U1mGlmAJ9EtQbmI39+qR12ar8kk5Zm2zskTIUmwCS88=" crossorigin="anonymous"></script> -->

</head>

<body>

    <div class="d-flex" id="wrapper">

        <!-- Sidebar -->
        <div class="bg-light border-right" id="sidebar-wrapper">
            <div class="sidebar-heading">Start Bootstrap </div>
            <div class="list-group list-group-flush">
                <a href="#" class="list-group-item list-group-item-action bg-light">Dashboard</a>
                <a href="#" class="list-group-item list-group-item-action bg-light">Shortcuts</a>
                <a href="#" class="list-group-item list-group-item-action bg-light">Overview</a>
                <a href="#" class="list-group-item list-group-item-action bg-light">Events</a>
                <a href="#" class="list-group-item list-group-item-action bg-light">Profile</a>
                <a href="#" class="list-group-item list-group-item-action bg-light">Status</a>
            </div>
        </div>
        <!-- /#sidebar-wrapper -->

        <!-- Page Content -->
        <div id="page-content-wrapper">

            <nav class="navbar navbar-expand-lg navbar-light bg-light border-bottom">
                <button class="btn btn-primary" id="menu-toggle">Toggle Menu</button>

                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav ml-auto mt-2 mt-lg-0">
                        <li class="nav-item active">
                            <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">Link</a>
                        </li>
                        <li class="nav-item dropdown">
                            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                Dropdown
                            </a>
                            <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                <a class="dropdown-item" href="#">Action</a>
                                <a class="dropdown-item" href="#">Another action</a>
                                <div class="dropdown-divider"></div>
                                <a class="dropdown-item" href="#">Something else here</a>
                            </div>
                        </li>
                    </ul>
                </div>
            </nav>



            <div class="container">
                <div class="row">
                    <div class="col">
                        COL 1

        <!-- CHART.JS HTML ETC -->
        <div id="chart-container">
            <canvas id="graphCanvas"></canvas>
        </div>


<script>
 var ctx = document.getElementById('graphCanvas').getContext('2d');
  var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: {!! json_encode($player_name) !!},
        datasets: [{
            label: 'player name',
            data: {!! json_encode($kills) !!},
            backgroundColor: ['rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero: true
                }
            }]
        }
    }
});
</script>



        <!--END OF  CHART.JS HTML ETC -->

                    </div>
                    <div class="col-md-auto">
                       COL 2
                    </div>
                    <div class="col col-lg-2">
                        COL 3
                    </div>
                </div>
            </div>


        </div>
        <!-- /#page-content-wrapper -->

    </div>
    <!-- /#wrapper -->


    <!-- BOOSTRAP JS FOR DROP DOWN MENU -->
     <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

    <!-- Menu Toggle Script -->
    <script>
        $("#menu-toggle").click(function(e) {
            e.preventDefault();
            $("#wrapper").toggleClass("toggled");
        });
    </script>

</body>

</html>
9
  • Does this answer your question? How to Decode Json object in laravel and apply foreach loop on that in laravel Commented Jun 18, 2020 at 0:55
  • it's a bit abstract for me. I'm looking at it Commented Jun 18, 2020 at 1:05
  • basically I'm trying to apply a foreach on the JSON labels: {!! json_encode($player_name) !!} and data: {!! json_encode($kills) !!}, Commented Jun 18, 2020 at 1:15
  • Where are you passing $player_name variable to the view? Commented Jun 18, 2020 at 1:31
  • yes. it echoes if I do @php foreach($player_stats as $player) { echo "['".$player->player_name."', ".$player->kills."],"; } @endphp but I can't figure out how to do this same type of behaviour in the json Commented Jun 18, 2020 at 1:35

3 Answers 3

1

Try mapping your result in the format you want first

class PlayerController extends Controller
{
    public function playerstats() {
        $players = Player::all();
        $player_names = $players->pluck('player_name');
        $player_kills = $players->pluck('kills');
        return view("show-players", compact(['player_names', 'players', 'player_kills']));
    }
}

Then simple @json it on the javascript

<script >
var player_kills = @json($player_kills);

var kills = [player_kills];

var player_names = @json($player_names);

var p_names = [player_names];

var ctx = document.getElementById('graphCanvas').getContext('2d');
var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: p_names[0],
        datasets: [{
            label: 'player name',
            data: kills[0],
            backgroundColor: ['rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero: true
                }
            }]
        }
    }
}); 
</script>
Sign up to request clarification or add additional context in comments.

16 Comments

It looks like you are on to something but I get this error ErrorException: array_map(): Expected parameter 2 to be an array, object given
Player::all() returns Collection and not array. You need to use map method to traverse it. laravel.com/docs/7.x/collections#method-map
This can help you to understand difference between all() and toArray() - stackoverflow.com/questions/43287573/…
@kevind just add toArray() method to the collection.
@kevind toArray() is forced on bny the @json in the view. without the toArray(), if you do {!! json_encode() !!} you will get the object version. but yeah in this case it seems the same but no performance change in the end. a toArray() is called in both versions.
|
0

I avoided the loop but got the chart.js bar chart to work correctly (refactoring needed)

Controller (PlayerController.php):

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Player;

class PlayerController extends Controller
{
    public function playerstats() {
        // $players = Player::all();
        $players = Player::all()->toArray();
        $player_kills = array_map(function($player) {
          return $player['kills'];
        }, $players);
        $player_names = array_map(function($player) {
          return $player['player_name'];
        }, $players);
        // return view("show-players", compact("player_stats"));
        return view("show-players", compact(['player_kills',
                                             'players',
                                             'player_names']));
    }
}

View (show-player.blade.php)

<script >
    var player_kills = @json($player_kills);
// console.log(player_kills); 
var kills = [player_kills];

var player_names = @json($player_names);
// console.log(player_names); 
var p_names = [player_names];

var ctx = document.getElementById('graphCanvas').getContext('2d');
var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: p_names[0],
        datasets: [{
            label: 'player name',
            data: kills[0],
            backgroundColor: ['rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero: true
                }
            }]
        }
    }
}); 
</script>

Comments

-2

use this in your controller:

dump($variable);

3 Comments

where exactly to add dump() ?
when I do $player_stats = Player::all(); dd($player_stats); it echos all the mysql data
@angel - If this was the help or debugging method that you were suggesting, please consider it adding in the comments section. As currently, the suggested solution is misleading wrt question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.