Svelteki api fetch pages - api

In short, I want to fetch data from diferents pages from one API I've made.
The API is https://joao-back-ecommerce-prod.herokuapp.com/store/ and as you can see I've multiples endpoints.
With svelte i'm trying to go from page to page in one click with increment function.
exemple:
<script context="module">
export async function load({ fetch, page }) {
const id = page.params.id;
const res = await fetch(
`https://joao-back-ecommerce-prod.herokuapp.com/store/products/?page=${id}`
);
const products = await res.json();
console.log(products);
if (res.ok) {
return {
props: {
products: products.results
}
};
}
return {
status: res.status,
error: new Error('Could not fetch the results')
};
}
</script>
<script>
export let products;
export let id = 1;
const next = () => {
id++;
};
</script>
<ul>
{#each products as product}
<li>
{product.title} - {product.description}
<a href={product.id}>hlmlll</a>
</li>
{/each}
<button on:click={next}>Next</button>
</ul>
I want to go to next page when click on button next. I thought that with increment id + 1 it will be work, but, it doesn't.
In the browser when I change the page number it works.
Any help?

You are just changing a local variable, it does not affect the url.
What you would do is navigate to the next page by changing the url.
There are two ways to do this:
import { goto } from '$app/navigation';
const next = () => goto(`/product/${id+1}`); // change to get correct path for you
or, a better way is to actually just link to the next page instead:
Next
The second option is preferred because you are in fact navigating for which you should use a link (buttons are for actions), it will also work if the user has javascript disabled.
SvelteKit will not actually go to the server and load a new page, it will just fetch the data from the load function and update accordingly, the user will not notice they are on a different page, only the url changes.

Related

Dynamic Route Params from Form Submit

I have a form that is passing a string to a search page that uses that string to query an API and display results. When I submit the form, the URL is x/search/string?slug=string. I am looking for a way to keep the URL cleaner and have it be x/search/string.
My form code:
<script lang="ts">
let slug = '';
</script>
<form action={`search/${slug}`}>
<input bind:value={slug} name="slug" type="text" />
<button type="submit" />
</form>
My +page.server.ts code:
export const load: PageServerLoad = async ({fetch, params}) =>{
const fetchSearchResults = async (slug:string) => {
const res = await fetch(`https://openlibrary.org/search.json?q=${slug}`)
const data = await res.json();
return {data};
}
return {
results: fetchSearchResults(params.slug)
}
}
The URL x/search/string?slug=string provides the same results as x/search/string but I am positive I am doing something wrong. Any help or links to some examples that would help would be greatly appreciated.
The input in the form is sent as part of the form request, for GET that results in query parameters.
There are multiple options, e.g. remove the name attribute.
You could also move the element out of the form, but I would not recommend that, as it breaks things like being able to press Enter to submit the form.

How to make a div object when clicked to do something

I have 6 objects and here is an example of one of the objects:
<div class="item2"><div class="circle2"><img class="device2" src="Devices/mouse.png" alt="Mouse"></div></div>
and what I would like to do is when that object is clicked to pass a variable and activate a method in the backend and refresh the data on the page.
You can use fetch to retrieve data from the server (assuming you have a controller endpoint set up do do that). We would need a little more information as to where the variable is coming from and how you will use the data coming from the server trefine this answer.
<div class="item2" id="item2"><div class="circle2"><img class="device2" src="Devices/mouse.png" alt="Mouse"></div></div>
<script>
const i2 = document.getElementById('item2')
i2.addEventListener('click', function() {
let fetchUrl ="https://www.yourdomain.com/api?id=" + yourvariable;
fetch(fetchUrl)
.then(response => response.json())
.then(data => {
//do something with data
})
})
</script>

How I can increase the url number in load more data in Vue

I am implment show more data button that's data came from API (backend)
and the api url have number when this number (visable) change the data change
.post(`/account/api/auth/user/${userName}/posts/more/${visible}/`)
I created function that increse number by 3 but it seems not to work and the api had same number without change
$('#show_more_posts_button').on('click', ()=>{
visible += 3
console.log(visible)
this.showMore()
})
This the function of load more button
async showMore() {
var visible = 3
this.buttonText = 'Loading more images...';
const userName = this.$route.params.username
await axios
.post(`/account/api/auth/user/${userName}/posts/more/${visible}/`).then(response => {
this.more = response.data.data
});
this.buttonText = 'Show More';
},
The button of show more data
<button class="show_more_button" id="show_more_posts_button" ><p class="Show_more_profile">Show More <i class="fas fa-chevron-down" ></i></p></button>
#Ahmed it's hard to tell how all the pieces fit together from the amount of code you've shared, but within your showMore function you're instantiating a new variable called visibile and assigning it's value to 3 each time. So within this function it will always be 3.
This part here
async showMore() {
var visible = 3
...etc...
How about alternatively, from within the below on click listener, you instead pass in the newly updated visible variable as an argument to showMore. ie
$('#show_more_posts_button').on('click', ()=>{
visible += 3
console.log(visible)
this.showMore(visible)
})
which would change your showMore function to look like
async showMore(visible) {
this.buttonText = 'Loading more images...';
const userName = this.$route.params.username
await axios.post(`/account/api/auth/user/${userName}/posts/more/${visible}/`).then(response => {
this.more = response.data.data
});
this.buttonText = 'Show More';
},

Nuxt add parameters without page and without reload the page

I have a page with big list of data and some buttons for filtering.
for example 2 buttons to filter by status:
Complete status
Cancel status
I want when the user clicked on the complete the url to be changed to
http://demo.com/list?filter=complete
the page does not reloading, it just for get specific url foreach filter button.
How can I implement the code in Nuxt application?
You cannot use $route or $router to change url, it set a new html5 history state and reload the page. So, to change url without reloading, history.replaceState do the job. In your page or component:
methods: {
onClickComplete() {
if (!process.server) { // I'm not sure it's necessary
history.replaceState({}, null, window.location + '?filter=complete') // or use your own application logic: globalSiteUrl, $route... or queryString some vars...
}
}
}
At first you should change your route with "$route.push" or click on
these ways change the route without reloading
After than you can use "pages watchquery" to handle event of changing route
https://nuxtjs.org/api/pages-watchquery/
first create this helper function
export function getAbsoluteUrl(to) {
const path = $nuxt.$router.resolve(to).href
return window.location.origin + path
}
this is example for my tabs
watch: {
tab(value) {
if (!process.server) {
const url = getAbsoluteUrl({
params: { ...this.$route.params, activeTab: value }
})
history.replaceState({}, null, url) // or use your own application logic: globalSiteUrl, $route... or queryString some vars...
}
}
},

Riot JS unmount all tags in a page and then mount only one tag is not working

I am using Riot JS and in my index.html, I have 3 custom tags - header, login-panel and candidates-panel inside my body. In my main app.js, in the callback function of $(document).ready, I execute the current route and also register a route change handler function. In my switchView, I unmount all custom tags and then try to mount only the tag pertaining to the current view being switched. Here is my code. If I do unmount, then nothing is displayed on the page
index.html
<body>
<header label="Hire Zen" icon="img/user-8-32.png"></header>
<login-panel class="viewTag" id="loginView"></login-panel>
<candidates-panel id="candidatesView" class="viewTag"></candidates-panel>
<script src="js/bundle.js"></script>
</body>
app.js
function switchView(view) {
if(!view || view === '') {
view = 'login'
}
//unmount all other panels and mount only the panel that is required
//TODO: unmount all view panels and mounting only required panel is not working
//riot.unmount('.viewTag')
riot.mount(view+'-panel')
$('.viewTag').hide()
$(view+'-panel').show()
}
$(document).ready(function () {
RiotControl.addStore(new AuthStore())
RiotControl.addStore(new CandidatesStore())
riot.mount('header')
//register route change handler
riot.route(function (collection, id, action) {
switchView(collection)
})
riot.route.exec(function (collection, id, action) {
switchView(collection)
})
})
Answer for riot.js v2.1.0:
The function
riot.unmount(...)
is not available as far as I know. However, you can unmount saved tags.
mytag.unmount(true)
Source
The trick is to remember the mounted tags to be able to unmount them later:
var viewTag = riot.mount(document.getElementById('viewTag'))
viewTag.unmount(true)
You can store all those view tags in an object and loop them to unmount all and mount only the active one.
Source
Answer for 2.3.18
Based on the previous answer and this tutorial I have created following concept:
app.currentPage = null;
var goTo = function(page){
if (app.currentPage) {
app.currentPage.unmount(true); //unmount and keep parent tag
}
app.currentPage = riot.mount(page)[0]; //remember current page
};
riot.route(function() {
console.info("this page is not defined");
//do nothing (alternatively go to 404 page or home)
});
riot.route('/inventory', function(){
goTo('inventory');
});
riot.route('/options', function() {
goTo('options');
});
I think you are looking for riot.util.tags.unmountAll(tags)
How to achieve the goal?
index.html
var tags = [];
some.tag.html
var some = this;
tags.push(some);
unmountAllTags.js
riot.util.tags.unmountAll(tags);