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? - promise

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>

Related

Differences between data in vue

I have tried to figure out why this happens but I have no idea why. I am going to post the code and then explain what happens. The issue is I do not know WHY this happens and it's annoying me like crazy!
Button:
<a
href="#"
v-for="(userStories, userStoriesIndex) in storiesData"
:key="userStoriesIndex"
#click="openUserStories(userStoriesIndex)"
>
Which loads:
<Stories v-for="(userStories, userStoriesIndex) in storiesData"
:key="userStoriesIndex"
>
<Story v-for="(story, storyIndex) in userStories.stories"
:key="storyIndex"
user-link="#"
:name="userStories.model.name"
:date="story.created_at"
close-button
#closeButtonClick="onCloseButtonClick"
>
<template #avatar>
<img :src="userStories.model.profile_photo_path" />
</template>
<img :src="story.media.preview_url" />
</Story>
</Stories>
And storiesData is loaded from this method:
getStories() {
axios
.get("/stories")
.then((response) => (this.storiesData = response.data));
}
which is loaded during mounted()
its loaded into:
data() {
return {
storiesData: [],
Now, when I click the button, the model loads incomplete, it is not loading the data... but... and this is where I lose it...
If I take the data from the Axios request, convert it to a JS object, and add it to the Vue file, everything works as intended.
I am not sure what's going on. I am completely at a loss why local would work and Axios would not. The data is IDENTICAL including but not limited to looking at Vue DevTools.
This sound to me like a bad async handling, Axios (and any other AJAX library), send the request asynchronously. It look like you thought that the rendering would wait for the ajax request to finish, but it is not. Try convert the axios call into Async/Await:
async function getStories() {
const data = await axios.get("/stories");
return data;
}
or for short:
async function getStories() {
return await axios.get("/stories");
}
then in your hydration function:
this.storiesData = await getStories();

Livewire the page has expired when setting properties or calling methods

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>

CkEditor5 insertContent Function not working

I am trying to use insertContent method but getting some error.
Here is my implementation
<div id="editor">
<p>This is the editor content.</p>
</div>
<button onclick="update()">update</button>
<script src="./node_modules/#ckeditor/ckeditor5-build-classic/build/ckeditor.js"></script>
<script>
var editorInstance;
ClassicEditor
.create(document.querySelector('#editor'))
.then(editor => {
editorInstance = editor;
})
.catch(error => {
console.error(error);
});
function update() {
editorInstance.model.insertContent("<p><b>Test</b> Content</p>")
}
</script>
update method should update the editor source with given content, but I am getting an error
Error on the console:
Uncaught TypeError: e.is is not a function
at xc.Nm (converters.js:777)
at xc.fire (emittermixin.js:209)
at xc. [as insertContent] (observablemixin.js:259)
at update (ck5.html:19)
at HTMLButtonElement.onclick (ck5.html:4)
Can anyone please help in sorting out this issue?
This error appears to be caused by trying to use the insertContent method to insert HTML - this method seems to expect a plain text string by default, although we can make it accept HTML with a few extra steps.
First of all, you'll need to grab the HTML Data Processor:
const htmlDP = editorInstance.data.processor;
Next you need to convert your HTML string into a viewFragment using the HTML Data Processor that we just obtained:
const viewFragment = htmlDP.toView("<p><b>Test</b> Content</p>");
Last of all, we need to convert the viewFragment to a modelFragment:
const modelFragment = editorInstance.data.toModel( viewFragment );
Now we can pass the modelFragment to the insertContent method:
editorInstance.model.insertContent(modelFragment);
This should remove the error and allow the mark-up string to be inserted into the editor

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');

Jade html not updated after a redirect in Express.js

I'm currently having some trouble displaying a flash message in Express.js using Jade's templating engine and connect-flash. I am simply trying to flash an error message when the user tries to add a new User object to my database that already exists. However the flash message is not showing up on my page after calling router.post and redirecting back to the index (code below).
Through various console.logs and debugging, I have found that the data I am posting is indeed posting correctly, and the flash message is being set. What I have found is that on the redirect, all of the correct data is passing to the Jade template, but the variables are not being updated in the file itself. I am now wondering if this is a session related issue, or just something Flash/Jade/Express related that I am completely overlooking?
In the code below I am logging session data as well as setting the flash message to a variable. If the array for the flash message(s) is empty (i.e. on page load), an array is set with a message that says so. If the flash message(s) array contains a flash message, the test array is set with a message that says so.
index.js:
router.get('/', function(req, res, next) {
console.log(req.session);
var testArray;
var errorMessages = req.flash('user-error');
if (errorMessages.length === 0)
testArray = ['errorMessages is empty'];
else
testArray = ['errorMessages contains a message now'];
console.log(errorMessages);
console.log(testArray);
res.render('index', {
message: errorMessages,
tester: testArray,
...other irrelevant vars being passed...
});
});
router.post('/add', function(req, res, next) {
var ajaxData = req.body;
console.log(ajaxData);
User.findOne({name: ajaxData.name}, function(err, user) {
if (err) return console.error(err);
// if User DNE already in DB
if (user === null) {
...new user created and saved here...
}
/*where the important stuff begins*/
else {
console.log("flash message set");
req.flash('user-error', "A user with that name already exists!");
}
// redirect to index
res.redirect('/');
});
});
In my Jade template, I'm again logging errorMessages and testArray to make sure everything is passed to the file correctly (it is) then showing the variables.
index.jade
-console.log(message);
-console.log(tester);
.error-box Error: #{message}
.error-box Error: #{tester}
Initially loading the page, I will get the following HTML output:
<div class="error-box">Error: </div>
<div class="error-box">Error: errorMessages is empty</div>
No surprises here. But when I submit the form with data that sets the error flash message, I get the updated logs from router.get('/') and index.jade with both the correct errorMessages and testArray variables. However my HTML output remains the same:
<div class="error-box">Error: </div>
<div class="error-box">Error: errorMessages is empty</div>
Clearly the variables being passed to Jade are being updated correctly, but it appears that Jade is simply not updating the HTML. With my somewhat limited knowledge of how connect-flash and Jade work, this would lead me to believe that this is a session related issue, however my code in app.js appears to be setup correctly...
var session = require('express-session');
var flash = require('connect-flash');
app.use(session({
secret: 'secret',
cookie: { maxAge: 60000 },
resave: false,
saveUninitialized: false
}));
app.use(flash());
I am relatively new to Express.js, so I feel like there might be something small I am overlooking or don't understand, but I've tried to be as detailed as possible so I'm hoping someone can help me out here!
After more careful inspection, I found that what was really causing the issue was that res.redirect('/') was not running, as I was attempting to use AJAX on the client side to call router.post('/add').
I solved this by simply removing my AJAX request, then going back into my HTML and changing my form's attributes (the form whose data I was sending via AJAX) to include method="POST" and action="/add". This is the proper way to make a SERVER SIDE call to my router.post('/add').
I found that someone was having the same problem here, and this question initially led me to look into the AJAX/Client Side vs. Server Side issue. I found the latter question in a comment from #herbyme on this post.

Resources