Jan Kožušník
Jan Kožušník

Reputation: 693

Laravel5 AJAX set cookie not working

Could you give me advice please?

I'm saving in COOKIES some data. I create method for this in Laravel, so I call ajax on this method to set cookie but when I try to call next request where I access this cookie value, it is not saved and I can access it in second request... I don't know why... it's quite strange :/

I have this code:

public function setCookie: method in laravel controller to set cookie
var setCookie: function in javascript where I call ajax request to set cookie
var loadEvents: method called after ajax call where I set cookie.


public function setCookie(Request $request) {

    $cookieName = $request->input('cookie_name');
    $cookieVal = $request->input('cookie_val');

    return response()->json(['status' => 'success'])->withCookie(cookie($cookieName, $cookieVal));
}


var setCookie = function (cookieName, cookieVal) {
    $.ajax({
        type: 'POST',
        url: window.setCookieUrl,
        data: {
            cookie_name: cookieName,
            cookie_val: cookieVal,
            _token: getCsrfToken()
        }
    }).done();
};



public function loadEvents(Request $request) {

    $activeCalendarsIds = $request->input('active_calendars_ids');
    if($activeCalendarsIds == null)
        $activeCalendarsIds = Cookie::get('adminActiveCalendars');


    $eventsPage = $this->getPostParam('page');
    $eventsLimit = $this->getPostParam('limit');

    $this->service->setFilter('page', $eventsPage);
    $this->service->setFilter('limit', $eventsLimit);

    $events = $this->service->getCalendarsEvents($activeCalendarsIds);
    $eventList = view('admin/calendar/event_list', ['events' => $events]);

    return response()->json([
        'status' => 'success',
        'data' => '' . $eventList . ''
    ]);

}

Upvotes: 2

Views: 6792

Answers (1)

luchaos
luchaos

Reputation: 1491

Update: the following works as expected. It seems there's a mixup in the order the requests are stated. The setCookie ajax request must be finished before any loadEvent ajax request is sent.

Controller actions:

public function set(Request $request)
{
    $cookieName = $request->input('cookie_name');
    $cookieVal = $request->input('cookie_val');
    return response()->json(['previousCookieValue' => Cookie::get('adminActiveCalendars')])->withCookie(cookie($cookieName, $cookieVal));
}

public function events() {
    return response()->json([
        'cookieValue' => Cookie::get('adminActiveCalendars'),
    ]);
}

Javascript/jQuery:

var setCookie = function(cookieName, cookieVal) {
  console.log('Set cookie', cookieName, cookieVal);
  $.ajax({
    type: 'POST',
    url: '{{ route('cookies.set') }}',
    data: {
      cookie_name: cookieName,
      cookie_val: cookieVal,
      _token: '{{ csrf_token() }}'
    },
    success: function(response) {
      console.log('Response:', response);
    }
  });
};

var loadEvents = function() {
  console.log('Load events');
  $.ajax({
    type: 'GET',
    url: '{{ route('cookies.events') }}',
    success: function(response) {
      console.log('Response:', response);
    }
  });
};

Template:

<button onclick="loadEvents();" type="button">Load Events</button>
<button onclick="setCookie('adminActiveCalendars', 'Foo');" type="button">Set Cookie Foo</button>
<button onclick="setCookie('adminActiveCalendars', 'Bar');" type="button">Set Cookie Bar</button>

Console output:

Load events
Object {cookieValue: null} // initially empty
Set cookie adminActiveCalendars Foo
Response: Object {previousCookieValue: null}
Load events
Response: Object {cookieValue: "Foo"} // first loadEvents request after setting cookie already holds correct value
Set cookie adminActiveCalendars Bar
Response: Object {previousCookieValue: "Foo"}
Load events
Response: Object {cookieValue: "Bar"}

After fully reloading the page, then loading events:

Load events
Response: Object {cookieValue: "Bar"} // still here, right from the start

Notes on alternative approaches:

  • Without knowing the internals of the application - it seems setting the cookie on the client side would be sufficient
  • Alternatively, store this kind of information in a Session variable rather than in a Cookie if it's not needed for something else on the client side. There are some differences. First of all you would not have to bother handling cookies on both sides (client and server).
  • Alternatively, do not store this information anywhere - add it to the request as filter parameters.

Original answer:

This doesn't set a cookie:

return view('welcome')->withCookie(cookie($cookieName, $cookieVal, 45000));

This does:

$response = new \Illuminate\Http\Response('Test');
$response->withCookie(cookie($cookieName, $cookieVal, 45000));
return $response;

Adaption of:

Upvotes: 7

Related Questions