Error not properly passing message in sveltekit - javascript

I am having an issue where sveltekit error function found at this link is not passing message correctly. See below code for example. The css classes are windicss classes.
Here is my +page.server.ts
import { error } from '#sveltejs/kit'
import type { PageServerLoad } from './$types'
export const load: PageServerLoad = ({ url }) => {
throw error(404, {
message: 'Not found',
code: 'NOT_FOUND'
})
}
Here is the +error.svelte page
<script lang="ts">
import { page } from '$app/stores'
import turtle from '$images/error/turtle-optimized.webp'
</script>
<section class="flex flex-col justify-around">
<div class="flex flex-row justify-center">
<h1>
{$page.status}
{#if $page.error}
<!-- Debugging line below -->
{JSON.stringify($page.error)}
: {$page.error.message}
{/if}
</h1>
</div>
<span class="flex flex-row justify-center">
Home
Shop
</span>
<span class="grid justify-center">
<img class="rounded-[8%]" width="400rem" src={turtle} alt="Sea turtle" />
</span>
</section>
I have tried to pass the message to the error page and display using
JSON.stringify($page.error)
the value that is displayed is
{"message":"Error: 404"}
I expect the value for
JSON.stringify($page.error)
to be
{"message":"Not Found"}

You haven't specified whether or not you have a corresponding +page.svelte file for the +page.server.ts, but if you don't my guess is that SvelteKit will throw its own 404 error if you don't handle it, and that is taking precedence over your own. Additionally, I'm pretty sure that any error inside a page.server.ts will simply pass as either a default 404 or a vague Internal Error before being passed to the client. Perhaps take a look at the SvelteKit Docs for some more info on this. How you handle your error will depend on your specific situation, so more info on what you are trying to accomplish would be great.

Related

React refreshes component after function call

I'm trying to create a portfolio where to display all of my ML projects that can be displayed with a simple API call and I decided to create a WebApp. I'm using React for the frontend and Django for the backend. The goal is to make a single page that doesn't need to refresh or change the page.
I've pretty much done everything, but on testing the API for the first project, I notice that after the API's function call, the page refreshes and I can't seem to figure out why it does.
App Component:
class App extends Component {
constructor(props) {
super(props);
this.state = {
menu: 1,
file: null
};
}
fileSelect = event =>{
this.state.file = event.target.files[0];
}
update_menu_item(new_item){
this.setState({menu: new_item});
}
// HERE PROBLEM
uploadSelfie(){
const fd = new FormData();
fd.append('image', this.state.file)
axios
.put("http://127.0.0.1:8000/api/obtainFaceEmotionPrediction", fd)
.then((response) => {
if (response.data){
// window.alert(response.data.file);
// Here even if I were to delete everything in this if statement, it would still refresh the page
document.getElementById("article").innerHTML +=
"<img src='../frontend/public/pictures_saved/face_emotion/" + response.data.file + "'/>";
}
})
.catch((err) => console.log(err));
}
uploadMilitary(){
// code not finalized yet. will be similar with uploadSelfie function but will handle multiple pictures
}
generate_segment(){
let uiItems = [];
if(this.state.menu === 1){
uiItems.push(
<article id="article">
<h2 id="title">My ML Projects</h2>
<div id="options">
<ul>
<li><button className="active" id="about" onClick={(e) => this.update_menu_item(1)}>About</button></li>
<li><button id="face_emotion_detection" onClick={(e) => this.update_menu_item(2)}>Face Emotion Detection</button></li>
<li><button id="military_detection" onClick={(e) => this.update_menu_item(3)}>Military Detection</button></li>
</ul>
</div>
<p>The scope of this application is to showcase all of the ML projects that I have finished. The application features a WebApp where the frontend is designed in React and the backend in Django.</p>
<p>Using REST API I'm able to make a call from the frontend to the backend. There, depending on the selected project, a pre-trained ML model will take your input and serve your request.</p>
<p>If you want to check the source code for each of these projects and more, you can do so by using this link.</p>
</article>
)
}
else if(this.state.menu === 2){
uiItems.push(
<article id="article">
<h2 id="title">My ML Projects</h2>
<div id="options">
<ul>
<li><button id="about" onClick={(e) => this.update_menu_item(1)}>About</button></li>
<li><button className="active" id="face_emotion_detection" onClick={(e) => this.update_menu_item(2)}>Face Emotion Detection</button></li>
<li><button id="military_detection" onClick={(e) => this.update_menu_item(3)}>Military Detection</button></li>
</ul>
</div>
<p>The aim of this project is to detect both the face and the emotion of a person. Upload a selfie with you and see how the model works:</p>
<input
type="file"
name="picture"
id="picture"
placeholder="Upload a Selfie"
onChange={this.fileSelect}
/>
<input
type="button"
value="Submit"
onClick={(e) => this.uploadSelfie()}
/>
</article>
)
}
else{
uiItems.push(
<article id="article">
<h2 id="title">My ML Projects</h2>
<div id="options">
<ul>
<li><button id="about" onClick={(e) => this.update_menu_item(1)}>About</button></li>
<li><button id="face_emotion_detection" onClick={(e) => this.update_menu_item(2)}>Face Emotion Detection</button></li>
<li><button className="active" id="military_detection" onClick={(e) => this.update_menu_item(3)}>Military Detection</button></li>
</ul>
</div>
<p>The aim of this project is to detect military personnel from an input data. The input can be a picture or a video, however for this WebApp, currently it is supported only images input. If you would like to test the video feature, check out the git repository. Upload a picture with military personnel and see how the model works:</p>
<input
type="file"
name="picture"
id="picture"
placeholder="Upload a Picture with Military"
onChange={this.fileSelect}
/>
<input
type="button"
value="submit"
onClick={(e) => this.uploadMilitary()}
/>
</article>
)
}
return uiItems;
}
render(){
return(
<main>
{this.generate_segment()}
</main>
);
}
}
export default App;
The API returns a simple strings and save a picture on the SSD:
API view:
#api_view(['PUT'])
def obtainFaceEmotionPrediction(request):
if request.method == 'PUT':
if request.FILES.get("image", None) is not None:
img = request.FILES["image"]
img = img.read()
model = FaceEmotionRecognition()
img = model.detect_emotion(img)
dir = '../frontend/public/pictures_saved/face_emotion/'
for f in os.listdir(dir):
os.remove(os.path.join(dir, f))
cv2.imwrite('../frontend/public/pictures_saved/face_emotion/face_emotion_1.png', img)
return Response({'file': 'face_emotion_1.png'})
There is 1 error and 1 warning that I have in the console but I can't seem to understand if they are related to the problem:
Also, the API call happens smoothly:
I've tried to write and rewrite the code in different ways. I've tried to use event.preventDefault() and other variants but nothing seems to work. Something that I would like to add is that the current code works, and does exactly what I want it to do, except it reloads the page.
I would very much appreciate your help.
I wound the solution. The problem was in the API, to be more specific here:
cv2.imwrite('../frontend/public/pictures_saved/face_emotion/face_emotion_1.png', img)
Basically, in the Django server, I was saving a picture into the React server files. React "saw" that there were changes in the files (new files added/modified. not necessarily to edit a .js or .css. just add a simple .png) and re-rendered the whole page. Why does it work like that? I have no clue. I changed the path where the image would be saved to be outside the React's server files and it worked like a charm.

SWUP works on initial page load, fails on first request, and succeeds on every subsequent request?

I am using Swup.js with a Laravel project that also uses Livewire. I almost have it working right, but I'm getting a bizarre error.
Here's the situation:
The first page loads perfectly fine. Everything works as intended.
Once you click a swup link and "load" your next page, everything fails. No Javascript will be executed, Livewire can't function, either.
But, once you make your second trip to that page by clicking the link, it's as if everything has loaded correctly in cache and is working - Javascript, Livewire, everything seems fine.
I can't figure out why this is happening. Here is my setup + code:
app.js:
import Swup from 'swup';
import SwupScriptsPlugin from '#swup/scripts-plugin';
import SwupLivewirePlugin from '#swup/livewire-plugin';
const swup = new Swup({
cache: false,
debugMode: true,
plugins: [
new SwupLivewirePlugin(),
new SwupScriptsPlugin({
head: true,
body: true,
optin: true
}),
]
});
My master blade template, layouts.app.blade.php:
...
<livewire:scripts />
<main id="swup">
#yield('content')
<script data-swup-ignore-script src="{{ asset('js/app.js') }}"></script>
#yield('js')
</main>
...
My home.blade.php file:
#extends('layouts.app')
#section('content')
<section class="mt-24 mb-32 py-12 relative">
<div class="max-w-7xl mx-auto px-4">
<div class="flex flex-col space-y-3 lg:w-1/2 w-full ml-auto">
<span class="block text-3xl xl:inline">I'm a...</span>
<span id="role" class="block text-indigo-600 xl:inline text-7xl">Hymn Writer</span>
</div>
</div>
</div>
</div>
</section>
#endsection
...
#section('js')
<script data-swup-reload-script src="https://cdnjs.cloudflare.com/ajax/libs/TypewriterJS/2.17.0/core.min.js" integrity="sha512-o6alMAMTI5qAmVC1UvuRPgTl3UOOkP8NZ6212+rq1Oslsuy8Owt9r5Z0Wu0LNxpw/Q8N8ToGiyovHV+kyOulxg==" crossorigin="anonymous"></script>
<script data-swup-reload-script>
function init() {
var role = document.getElementById('role');
var typewriter = new Typewriter(role, {
loop: false,
});
typewriter.typeString('Hymn Writer')
.pauseFor(2400)
.deleteAll()
.typeString('Father')
.pauseFor(2400)
// ...etc
.start();
}
init();
document.addEventListener('swup:contentReplaced', init);
</script>
#endsection
I can't figure out why it's working on initial page load and subsequent link clicks but not the very first time the link is clicked when starting from another page? What is going on here?

[Vue warn]: Error in callback for watcher "childItems": "TypeError: Cannot read property 'tag' of undefined"

I am currently working on the Store page of a webapp I am building using Axios to fetch product data and then display it in a vue template. All the backend works and the front end renders successfully as well, however Vue gives a Warning twice in the console stating:
Error in callback for watcher "childItems": "TypeError: Cannot read property 'tag' of undefined"
To combat this, I have tried wrapping the v-for for iterating products in a v-if that is set to true by the async getProducts function which sends a get request for the product data to display. I have tried moving around where the getter function is, placing it in Mounted, beforeMount, created, used vue-async-computed and all have rendered fine but none have gotten rid of the error.
Here is my store.vue file:
<template>
<div id="store">
<section>
<b-tabs>
<div class="container">
<div v-if="fetchComplete">
<b-tab-item v-for="(product, index) in products" :label="product.categories[0].title" :key="index">
<div class="card">
<div class="card-image">
<figure class="image">
<img :src="'http://localhost:1339'+ product.product_color_imgs[0].img[0].url" :alt="product.title">
</figure>
</div>
<div class="card-content">
<p class="title is-4">{{product.title}}</p>
</div>
</div>
</b-tab-item>
</div>
</div>
</b-tabs>
</section>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
products: [],
fetchComplete: false
}
},
async beforeCreate() {
await axios({
method:'get',
url:'http://localhost:1339/products'
}).then(res => {
this.products = res.data;
this.fetchComplete = true;
}).catch(err => {
console.log(err);
})
}
}
</script>
In this version I used beforeCreate but I have tested it with the other life-cycle functions. My guess is that the promise from beforeCreate returns after the page has rendered the first time.
Note: I am relatively new to Vue.js so it is possible I may have overlooked something
Thank you in advance!
This is caused by placing the <div> tags inside of the <b-tabs> component but ouside of a <b-tab-item>. It seems that <b-tabs> requires that no element other than a <b-tab-item> be placed in the slot root.
Try moving the divs outside of that component like:
<div class="container">
<div v-if="fetchComplete">
<b-tabs>
<b-tab-item v-for...>
...
</b-tab-item>
</b-tabs>
</div>
</div>

Vue TypeError: Cannot read property '_wrapper' of undefined when attempting to update Object property

I am trying to use a button to update a property of an Object in Vue. The Object is returned by an AJAX query to a database, and the isFetching boolean is then set to false, which attaches the containing div to the DOM. When I try and update the property, I get the following error:
TypeError: Cannot read property '_wrapper' of undefined
Below is my AJAX code:
axios.post("/api/myEndpoint", { id: router.currentRoute.query.id })
.then((response) => {
this.activities = response.data.activities;
this.isFetching = false;
})
.catch((errors) => {
console.log(errors);
router.push("/");
});
Here is my HTML:
<div v-if="isFetching">
<h2>Loading data...</h2>
</div>
<div v-else>
<div class="row no-gutters">
<div class="col">
<div class="d-flex flex-row justify-content-center">
<h4>Activities</h4>
</div>
<div class="custom-card p-2">
<div class="row no-gutters pb-4" v-for="(activity, index) in activities"
:key="activity.stage_id">
<button v-if="!activity.is_removed" class="btn custom-btn" :class="{'hov':
index == 0}" :disabled="index != 0"
#click="markRemoved(activity)">Remove</button>
</div>
</div>
</div>
</div>
</div>
Finally, here is markRemoved() as called by the button's click listener:
markRemoved(a) {
a.is_removed = true;
}
When I try and log a in markRemoved() the Object is logged to the console fine, exactly as expected. Having stepped through it in the debugger, the exception is thrown at the point I try and update the is_removed property of the Object.
Does anyone know what I'm doing wrong here?
Note: the id I pass to the AJAX query is a query parameter of Vue Router. This is also set correctly and passed as expected.
Here is an example activity Object:
{date_time_due: "2020-12-09T11:43:07.740Z"
date_time_reached_stage: "2020-12-02T11:43:07.740Z"
is_complete: true
is_removed: false
selected_option: "Some text"
stage_id: 1
stage_name: "Some text"}
The exception is only thrown on the first click of the button.
Posting in case anybody else comes across this error in the future.
Vue requires exactly one root element within a single-file component's <template> tags. I had forgotten about this and in my case had two <div> elements, shown one at a time, conditionally using v-if:
<template>
<div v-if="fetchingData">
<h2>Loading data...</h2>
</div>
<div v-else>
<!-- The rest of the component -->
</div>
</template>
This caused problems with Vue's reactivity, throwing the error whenever I tried to update some part of the component. After realising my mistake, I wrapped everything in a root <div>. This solved the issue for me:
<template>
<div id="fixedComponent">
<div v-if="fetchingData">
<h2>Loading data...</h2>
</div>
<div v-else>
<!-- The rest of the component -->
</div>
</div>
</template>

Cannot read property 'map' of undefined even after API fetched correctly in console in Async

Hi I am trying to create a API based news search webapp using JS. So here's the function where I am getting the error
async function fetchUsers(searchTerm, searchLimit, sortBy){
//RETURNS PROMISES
let url=`some api parameters searchTerm, SearchLimit and sorby is passed`;
const res=await fetch(url);
const data=await res.json();
const article = [];
document.getElementById("container").innerHTML=`
${data.article.map(function(post){
//NEWSCARD
return(`
<ul id="news-article" style="list-style-type:none;">
<li class="article">
<div class="card mb-2">
<img class="article-image" class="card-img-top" src="${post.urlToimage}" alt="Card image cap">
<div class="card-body">
<h2 class="article-title" class="card-title">${post.title}</h2>
<p class="article-description" class="card-text">${truncateString(post.selftext, 100)}</p>
<a class="article-link" href="${post.url}" target="_blank
" class="btn btn-primary">Read More</a>
<hr>
<span class="article-author" class="badge badge-secondary">Subreddit: ${post.subreddit}</span>
<span class="badge badge-dark">Score: ${post.score}</span>
</div>
</div>
</li>
</ul>
`)
}
.join('')
)}} fetchUsers();
The main error is observed at ${data.article.map(function(post){
Could anyone suggest what could be the possible reason for it ?
Thanks
The only way to narrow down and find the issue is to first write the code in clean way.
I would suggest breakdown your code in manageable parts and try debug features in browser with debugger or console.log() works really well.
There are even better options like TDD where you can write your code and test it with the help of code to get more confidence with tools like jest
NOTE: pseudo code
function getPosts() {
return posts
}
function renderPost(post) {
return `<div>${post}</div> `
}
function render() {
const posts = getPosts()
console.info('post -> ', posts)
const postsMarkup = posts.map((post) => renderPost(post)).join('');
console.info('postsMarkup -> ', postsMarkup)
document.getElementById('container').innerHTML = postMarkup
}
What is happening is that the document.getElementByid section is being called asynchronously, perhaps at a time when the data has not returned anything, or when the article variable is not even declared, you can try this:
async function getData() {
const res = await fetch(url);
const data = await res.json();
populateList(data);
}
function populateList(article) {
const innerHTML = article.map(post => `
<ul id="news-article" style="list-style-type:none;">
<li class="article">
<div class="card mb-2">
<img class="article-image" class="card-img-top" src="${post.urlToimage}" alt="Card image cap">
<div class="card-body">
<h2 class="article-title" class="card-title">${post.title}</h2>
<p class="article-description" class="card-text">${truncateString(post.selftext, 100)}</p>
<a class="article-link" href="${post.url}" target="_blank" class="btn btn-primary">Read More</a>
<hr>
<span class="article-author" class="badge badge-secondary">Subreddit: ${post.subreddit}</span>
<span class="badge badge-dark">Score: ${post.score}</span>
</div>
</div>
</li>
</ul>
`);
document.getElementById('container').innerHTML = innerHTML;
}
The issue (from observing the error in the console) is that your code is attempting to access a property that doesn't exist.
Without access to the exact data that you're using, it'd be impossible to inform you of what the exact problem is. However, here are some steps I'd take to diagnose the issue:
Set up a breakpoint (debugger) or a console.log(data) right after data is assigned so that you can observe it.
Either click through the data variable in your browser's dev tools, or check the assumptions your code is making programmatically.
In terms of programmatically checking your code's assumptions:
Verify that data is an object by running typeof data should return object
Verify that data does in fact have a property article by running Object(data).hasOwnProperty('article')
Verify that data.article is an array by running Array.isArray(data.article)
Verify that each article within data has a selfText, subreddit, score (using step 2)
My guess is you'll find a misalignment between your code and the data in this process. If not, I'd like to know where you land.
You can also do this without the async and await keywords, and just use a callback within a .then statement, like this:
function fetchUsers(searchTerm, searchLimit, sortBy){
let url=`some url based on params`;
fetch(url)
.then( res => res.json() )
.then( data => populateList(data) )
}
function populateList(data) {
const innerHTML = data.articles.map(post => `
<ul id="news-article" style="list-style-type:none;">
<li class="article">
<div class="card mb-2">
<img class="article-image" class="card-img-top" src="${post.urlToimage}" alt="Card image cap">
<div class="card-body">
<h2 class="article-title" class="card-title">${post.title}</h2>
<p class="article-description" class="card-text">${truncateString(post.selftext, 100)}</p>
<a class="article-link" href="${post.url}" target="_blank" class="btn btn-primary">Read More</a>
<hr>
<span class="article-author" class="badge badge-secondary">Subreddit: ${post.subreddit}</span>
<span class="badge badge-dark">Score: ${post.score}</span>
</div>
</div>
</li>
</ul>
`);
document.getElementById('container').innerHTML = innerHTML;
}
fetchUsers(searchTerm, searchLimit, sortBy);
Also, hijacking Misir Jafarov's comment, the array in your data object is called articles, but you're trying to map from article. I feel like you'd still have problems without this typo, but that will definitely hang you up. Thanks #Misir Jafarov

Categories

Resources