XanCeegor's avatar

Mark As Read not updating Unread notification count as expected

I posted this question on StackOverflow but hasn't gotten any helpful responses. I will link it below to save having to repeat it again here.

https://stackoverflow.com/questions/57077853/mark-as-read-not-updating-unread-notification-count-as-expected

The TL;DR version is that when I click on "Mark as Read" for a notification, it doesn't seem to refresh the count properly. I think it might be because Laravel caches my Navbar. Only when I actually refresh the page manually or go to a different page after marking the notification as read does it decrement the unread notification count. The StackOverflow link above has a lot more detail and the code I am using.

Any assistance would be appreciated.

0 likes
5 replies
mstrauss's avatar

Your SO post seems to state the question slightly differently:

When the user clicks on "Mark as Read" the page redirects back and the number is decremented by 1, as expected. However, when the user clicks on "View Request", the page redirects to the relevant page but the number doesn't decrement.

Whereas this post says:

when I click on "Mark as Read" for a notification, it doesn't seem to refresh the count properly.

But, I believe the issue is the page refresh. return redirect() refreshes the page where as return view is just responding to a URI and will not refresh the page contents. That may be why you see the update when they simply click mark as read because the response in the controller is a redirect.

That being said, the I don't think it would be improper to add a redirect to redirect he user to the correct view if they click View Request. Since you are building the URI based on their request data and not responding directly to a click on a link.

XanCeegor's avatar

Thanks for your response. From what I've read online with regards to the difference between return view() and redirect(), is that redirect() is mainly used after submitting a POST request and return view() when a GET request is used. As far as I can see what I'm going is "right".

If I were to use a redirect(), is there a way to pass the Object to the relevant View without having to pass it to the session first and then access it through the session on the View? The View already receives the Object from other controller methods, so I'd prefer not to have to rewrite the View just for this one function.

Also, you could call this a theoretical question, but why doesn't the page get refreshed completely when a View is returned vs when a redirect() function is called?

mstrauss's avatar

Hey @xanceegor

I don't think you're doing it wrong at all. I just suggested using the redirect as you need the view's data to be refreshed and it seems like the return view is not doing that.

If I were to use a redirect(), is there a way to pass the Object to the relevant View without having to pass it to the session first and then access it through the session on the View?

 // assuming leave.show is a named route
    if($leavenr !== "null"){
        return redirect()->route('leave.show', ['leavereqs' => Leave::where('leavenr', $leavenr)->first()]);
    } else{
        return redirect()->back();
    }

Also, in the docs, there is an example of using redirect with the get method: https://laravel.com/docs/5.8/redirects#creating-redirects

Route::get('dashboard', function () {
    return redirect('home/dashboard');
});

So I don't think it's a hard rule that redirect() is only used with Post requests, thought that is my typical use. But, in your case, if it makes sense to use the redirect with a Get type request, I don't think anyone would be too critical about that.

mstrauss's avatar

As far as why the page is refreshed with the return redirect() versus return view, see below:

With return view: (helpers.php)

    /**
     * Get the evaluated view contents for the given view.
     *
     * @param  string  $view
     * @param  \Illuminate\Contracts\Support\Arrayable|array   $data
     * @param  array   $mergeData
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
     */
    function view($view = null, $data = [], $mergeData = [])
    {
        $factory = app(ViewFactory::class);

        if (func_num_args() === 0) {
            return $factory;
        }

        return $factory->make($view, $data, $mergeData);
    }

Then it calls the ViewFactory make method below: (Contracts/View/Factory.php)

    /**
     * Get the evaluated view contents for the given view.
     *
     * @param  string  $view
     * @param  \Illuminate\Contracts\Support\Arrayable|array  $data
     * @param  array  $mergeData
     * @return \Illuminate\Contracts\View\View
     */
    public function make($view, $data = [], $mergeData = []);

Whereas redirect() gets an instance of the Redirector class:

if (! function_exists('redirect')) {
    /**
     * Get an instance of the redirector.
     *
     * @param  string|null  $to
     * @param  int     $status
     * @param  array   $headers
     * @param  bool    $secure
     * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
     */
    function redirect($to = null, $status = 302, $headers = [], $secure = null)
    {
        if (is_null($to)) {
            return app('redirect');
        }

        return app('redirect')->to($to, $status, $headers, $secure);
    }
}

And it sends the user to that destination, where the view is built fresh. Versus grabbing the static view contents and building it up in the return view scenario.

Please or to participate in this conversation.