Livewire the page has expired when setting properties or calling methods - laravel

I'm trying to follow the instructions given in the Livewire docs to set livewire component properties or call methods in javascript. However, I keep getting "Page has expired" alert on Chrome?
<script>
document.addEventListener('livewire:load', function () {
//These work:
console.log(Livewire.first().foo)
console.log(#this.foo)
// These give the "The page has expired " error and freeze the page:
Livewire.first().bar()
#this.bar()
Livewire.first().foo = 'Hello world'
})
</script>

Related

An api call for Instagram is working but returning an error that the token in .env is undefined. I am using Nuxt3. How do I fix the error?

I would like to display a gallery of instagram images in a Nuxt3 component. Right now I am just trying to print the data returned from an API call to instagram.
This actually works - the data is returned and the template is displayed in the browser.
However, I get an error message that the token variable in .env is undefined.
When I print just the url to the console, it displays correctly in VScode terminal, but does not work in the browser console.
This is the error I am receiving:
instagram.vue:8 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'LMM_TOKEN')
Here is my .env
LMM_TOKEN="mytokenhere"
I have tried this both with quotes and without. I have also tried to useRuntimeConfig() but get the same error.
I am still really uncomfortable with doing API calls, so I suspect the problem is in my component (though it actually does print out the data!):
<template>
<div>
<pre v-if="feed">{{ feed.data }}</pre>
</div>
</template>
<script setup>
const instaToken = process.env.LMM_TOKEN
const url = `https://graph.instagram.com/me/media?fields=id,caption&access_token=${instaToken}`
const feed = ref({})
try {
const data = await fetch(url).then((res) => {
return res
})
feed.value = await data.json();
} catch (e) {
console.log(e)
}
</script>

Laravel Dusk: Wait for a load mask/overlay to finish

I am having difficulty getting some tests to pass because of a load mask I put over the entire screen during AJAX calls (transparent black with a loading gif in the middle).
I can get it to work if I pause(2000) each time, but the amount of AJAX calls in the app make that the slow solution. I am trying to use waitUntilMissing but it's not working.
I have a div with two classes: load-mask and loading.
load-mask is always there
loading class applied to div during all vue.js AJAX calls; this is the load mask
When AJAX response received, loading class removed
So in my test I am trying to do this:
$browser->loginAs($this->user)
->visit(new CustomInputPage)
->saveNarrative('Lorem ipsum dolor')
->visit(new CustomInputPage)
->waitUntilMissing('.load-mask')
->assertSee('Lorem ipsum dolor');
Load a page
Enter text & hit save
reload page
make sure text is still there
I get an error on the assertSee because once the page loads, the loading is applied as it makes it's AJAX call so it hasn't loaded the text yet.
I am assuming waitForMissing('.load-mask') is passing before the load mask even starts, so it tries to assertSee during the loading process, but it's an assumption.
Is there a working solution outside just using pause?
EDIT: I am currently trying to click around the page to reload the AJAX instead of a full page load. I am still experiencing the same issue.
Now I am trying this instead:
$browser->loginAs($this->user)
->visit(new CustomInputPage)
->saveNarrative('Lorem ipsum dolor')
->clickLink('Tab 2')
->waitUntilMissing('.load-mask')
->assertSee('Lorem ipsum dolor');
Clicking a tab will load the AJAX call I'm referring to. I notice in the screenshot it's always showing my .loading animation.
So...Tab 2 should be an empty box but the screenshot shows the text hasn't been cleared yet and load mask is still present (happens after response is received).
So I can't get the timing on a completed AJAX call down without using pause. Should I try another way?
EDIT 2
Here is where my load mask is being inserted. The vue.js axios library.
import store from '../store';
let numberOfAjaxCAllPending = 0;
axios.interceptors.request.use(function (config) {
// Do something before request is sent
numberOfAjaxCAllPending++;
store.commit('isLoading', true);
return config;
}, function (error) {
numberOfAjaxCAllPending = 0;
store.commit('isLoading', false);
// Do something with request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Do something with response data
numberOfAjaxCAllPending--;
if (numberOfAjaxCAllPending === 0) {
store.commit('isLoading', false);
}
return response;
}, function (error) {
numberOfAjaxCAllPending = 0;
store.commit('isLoading', false);
// Do something with response error
return Promise.reject(error);
});
And on each Laravel blade template, I tried this first:
<div :class="{ loading: $store.state.isLoading }" class="load-mask"></div>
But now I am trying this way, with the loading class always present and just toggling display none/block
<div :style="{display: $store.getters.getLoadingDisplay }" class="loading"></div>
Same issue occurs this way as well. The load mask is present and I am also noticing the text box isn't being cleared when switching tabs in Laravel Dusk (the tabs clear fine in a regular browser).
EDIT 3
The first assertion passes, then it fails when trying to ->press('Save'). I get this error:
Facebook\WebDriver\Exception\UnknownServerException: unknown error: Element <button type="button" class="btn btn-sm mt-3 btn-primary" style="float: left;">...</button> is not clickable at point (440, 912). Other element would receive the click: <div class="loading" style="display: block;"></div>
This is the test I am trying to run. As you can see, I have a waitUntilMissing and an assertMissing right after each other. Then I press Save and it says there's still a load mask. If I wait 2 seconds before the keys statement, it works fine.
$browser->loginAs($this->user)
->visit(new CustomInputPage)
->waitUntilMissing('.loading')
->assertMissing('.loading')
->keys('.ql-editor', 'Test Text')
->press('Save')
->waitUntilMissing('.loading');

AJAX pagination with CakePHP

I'm struggling to get some ajax pagination with cakephp working. I've read the instructions here and various other pages on the internet eg: SO link
However I get an error in the console:
Uncaught type error undefined is not a function
Which occurs on the $(document).ready() function generated by $this->Js->writeBuffer().
Any ideas on what I'm doing wrong?
In my view index.ctp I set the paginator's options:
$this->Paginator->options(array(
'update' => '#content',
'evalScripts' => true)
);
Then carry on with the remainder of the view, in particular I render the table. The controller has fetched data to be displayed.
I output my pagination controls:
echo $this->Paginator->prev();
echo $this->Paginator->numbers();
echo $this->Paginator->next();
At the end of my view I do:
echo $this->Js->writeBuffer();
I have added the relevant helpers and components to my controller:
public $helpers = array('Js' => array('jquery'));
public $components = array(
'Paginator',
'RequestHandler'
);
In default.ctp I have included jquery by adding this to the end of the HTML (just before </body>:
<script src="https://code.jquery.com/jquery.js"></script>
It looks it works in that it generated the relevant javascript and provides the id's for the links but clicking the links just works like normal.
Functions need to exist before they are called
In default.ctp I have included jquery by adding this to the end of the HTML (just before </body>
Jquery needs to be loaded before it is used. Ensure that script tags appear in the rendered html in this order:
<script src="//code.jquery.com/jquery.js"></script>
... anything or nothing ...
<script>
$(document).ready(
...

send hyperlink query string to server and get result using jquery ajax

i am making a simple site in php. I have a product page and there is a link on product page that says add to wishlist so when a user clicks on that link the product is posted to the server and the page is redirected from the backend. but I want to do it using jquery ajax so that my page is not reloaded. can somebody please provide a snippet of code on how to do that ?
$('#anchorId').click(function(){
$.ajax({
url:"foo",
data : "the query string",
...
...
success: function(result){
// success code.
}
});
return false; // prevents the default behavior of anchor click.
});
The best way to learn jQuery, is to visit the API site. (Which seems to be down at the moment)
The ajax category
Update:
$('body').on('click', 'a.foo', function(){
// What you want here.
return false;
}
This will catch any click on anchors with the foo class under <body> no matter when they were created("runtime" or with the page load) .

jquery with boxy plugin - load and submit a form via ajax

I am using JQuery with Boxy plugin.
When a user clicks on a link on one page, I call Boxy.load to load a form onto the pop-up. The form loads and is displayed inside the pop-up without problems.
However, I can't bind the form to a submit event, since I can't select the form element.
This is the event handler:
$('#flag-link a.unflagged').click (function(e) {
url = $(e.target).attr('href');
Boxy.load(url, {behaviours: function(r) {
alert ($("#flag-form").attr('id'));
}
});
});
The alert reads "undefined" when it is displayed.
And this is the form:
<form id="flag-form" method="POST" action="somepage">
<table>
<tr><td><input type="text" name = "name"></td></tr>
<tr><td><input type="submit" value="OK"></td></tr>
</table>
</form>
What am I doing wrong?
First (a minor point, but a potential source of trouble), it should be id="flag-form" not id = "flag-form" (no spaces).
Second, you shouldn't need r.find(). Just do $("#flag-form").attr("id")
As far as I understand, live() method must be used to bind an element to an event in this case:
$("#flag-form").live("submit", function(){ ... }
Presently, live method is documented to be not supporting the submit event. However, I could work it out with Chrome and FF. On the other hand, I couldn't get it working in IE. A better way for cross-browser compatibility seems to be binding the submit button of the form to the click event.
$("#flag-form-submit").live("click", function(){
I learnt that declaring methods in behaviours: function (e) {} works, in addition to using live() methods.
E.g.:
$('#flag-link a.unflagged').click (function() {
Boxy.load(this.href, {
behaviours: function(r) {
r.find('#flag-form').bind('submit', function() {
// do on submit e.g. ajax calls etc.
});
}
});
return false;
});
Boxy opens the URL (url = $(e.target).attr('href');) in an iframe. So you cannot find the form from the opening page(parent page). Your code to bind the form should be in the child page (ie, the Boxy iframe). You can check the iframe URL using your code, url = $(e.target).attr('href');

Resources