ngplayground
ngplayground

Reputation: 21627

Laravel and a While Loop

I'm new to Laravel and at the moment I have a piece of code in a Controller which without the while loop it works, it retrieves my query from the database.

public function dash($id, Request $request) {
        $user = JWTAuth::parseToken()->authenticate();
        $postdata = $request->except('token');

        $q = DB::select('SELECT * FROM maps WHERE user_id = :id', ['id' => $id]);

        if($q->num_rows > 0){
            $check = true;

            $maps = array();
            while($row = mysqli_fetch_array($q)) {
                $product = array(
                    'auth' => 1,
                    'id' => $row['id'],
                    'url' => $row['url'],
                    'locationData' => json_decode($row['locationData']),
                    'userData' => json_decode($row['userData']),
                    'visible' => $row['visible'],
                    'thedate' => $row['thedate']
                );
                array_push($maps, $product);
            }
        } else {
            $check = false;
        }

        return response()->json($maps);
    }

I am trying to loop through the returned data from $q and use json_decode on 2 key/val pairs but I can't even get this done right.

Upvotes: 1

Views: 31211

Answers (3)

erapert
erapert

Reputation: 1413

  1. You're not using $postdata in that function so remove it.
  2. Do not use mysqli in Laravel. Use models and/or the DB query functionality built in.
  3. You're passing the wrong thing to mysqli_fetch_array. It's always returning a non-false value and that's why the loop never ends.
  4. Why are you looping over the row data? Just return the query results-- they're already an array. If you want things like 'locationData' and 'userData' to be decoded JSON then use a model with methods to do this stuff for you. Remember, with MVC you should always put anything data related into models.

So a better way to do this is with Laravel models and relationships:

// put this with the rest of your models
// User.php
class User extends Model
{
    function maps ()
    {
        return $this->hasMany ('App\Map');
    }
}

// Maps.php
class Map extends Model
{   
    // you're not using this right now, but in case your view needs to get
    // this stuff you can use these functions
    function getLocationData ()
    {
        return json_decode ($this->locationData);
    }

    function getUserData ()
    {
        return json_decode ($this->userData);
    }
}

// now in your controller:
public function dash ($id, Request $request) {
    // $user should now be an instance of the User model
    $user = JWTAuth::parseToken()->authenticate();

    // don't use raw SQL if at all possible
    //$q = DB::select('SELECT * FROM maps WHERE user_id = :id', ['id' => $id]);
    // notice that User has a relationship to Maps defined!
    // and it's a has-many relationship so maps() returns an array
    // of Map models
    $maps = $user->maps ();

    return response()->json($maps);
}

Upvotes: 2

Ivan
Ivan

Reputation: 10372

You can loop over $q using a foreach:

foreach ($q as $row) {
  // Do work here
}

See the Laravel docs for more information.

Upvotes: 0

Jeff Lambert
Jeff Lambert

Reputation: 24661

Don't use mysqli to iterate over the results (Laravel doesn't use mysqli). Results coming back from Laravel's query builder are Traversable, so you can simply use a foreach loop:

$q = DB::select('...');
foreach($q as $row) {
    // ...
}

Each $row is going to be an object and not an array:

$product = array(
    'auth' => 1,
    'id' => $row->id,
    'url' => $row->url,
    'locationData' => json_decode($row->locationData),
    'userData' => json_decode($row->userData),
    'visible' => $row->visible,
    'thedate' => $row->thedate
);

Upvotes: 4

Related Questions