1
votes

I'm trying to create a search function in Laravel and its returning me with "undefined variable: posts" when I do foreach on my view.

My code:

Post Model

class Post extends Model { 

    protected $fillable = [ 
        'creator', 
        'post_url', 
        'books', 
        'likes', 
        'created_at' 
        ]; 

    public function user() { return $this->belongsTo(User::class); } 

}

Homeview:

<form action="{{ url('/search') }}" method="get">
   <input type="text" class="search-text form-control form-control-lg" name="q" placeholder="Search" required>
 </form>

Controller:

public function search($keyword)
    {
        $result = Post::where('books', 'LIKE', "'%' . $keyword . '%'")->get();
        return view('/search', ['posts' => $result]);
    }

Route:

Route::get('/search/{keyword}', 'SearchController@search');

Searchview:

@foreach($posts as $post)
  <div class="post">{{ $post->id }}</div>
@endforeach

What am I doing wrong here?

3
Try return view('search')->with('posts', $results);Brad Goldsmith
The problem is most likely that the controller isn't getting the keywordDerek Pollard
Yup, thats not working. How am I supposed to pass the keyword to the controller? @DerekPollardtweetok
@Jascusi remove $keyword from the parameters, and use this in the method: $keyword = request()->input('q');Derek Pollard
That makes more sense but I'm getting the same error.tweetok

3 Answers

1
votes

This might help you out.

Homeview.blade.php

<form action="/search" method="POST">
    @csrf // include your csrf token 

    <input type="text" class="search-text form-control form-control-lg" id="q" name="q" placeholder="Search" required>
</form>

Searchview.blade.php

<!-- or did you return a collection? --> 
@if( $posts->count() > 1 )

    <!-- then loop through the posts --> 
    @foreach( $posts as $post )
        <div class="post"> {{ $post->id }} </div>
    @endforeach

@else

    @if( !empty($posts) )
        <div class="post"> {{ $post->id }} </div>
    @endif 

@endif 

Routes/web.php

Route::post('/search', 'PostsController@show')->name('posts.show');

PostsController

use App\Post;

public function show( Request $request )
{

    $result = Post::where("books", "LIKE", "%{$request->input('q')}%")->get();

    // Uncomment the following line to see if you are returning any data
    // dd($result);

    // Did you return any results?
    return view('searchview', ['posts' => $result]);

}
0
votes

The reason it wasn't working,

Route::get('/search/{keyword}', 'SearchController@search');

In your route file you were looking for a {keyword} that was never passed by the form. Your form action is action="{{ url('/search') }}". A get variable will not be picked up by a route and if it was you called the input 'q' anyway.

So then in your controller you were looking for the keyword being passed that is never passed in.

public function search($keyword)

Instead the correct thing to do is pass in the Request object like so

public function search(Request $request)

Then use $request->input('q') to retrieve the passed value through your form.

In your example $keyword would always have been blank.

Corrected code

Homeview:

<form action="{{ url('/search') }}" method="get">
   <input type="text" class="search-text form-control form-control-lg" name="q" placeholder="Search" required>
 </form>

Controller:

public function search(Request $request)
{
    $result = Post::where('books', 'LIKE', "%{$request->input('q')}%")->get();
    return view('/search', ['posts' => $result]);
}

Route:

Route::get('/search', 'SearchController@search');

Searchview:

@foreach($posts as $post)
  <div class="post">{{ $post->id }}</div>
@endforeach
-1
votes

try:

return view('/search')->with('posts', $result);

Or even better with dinamic vars.

return view('/search')->withPosts($result);