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>
Related
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.
First of: I'm a beginner at Vue.js/APIs so I hope my question is not too stupid (I may not be seeing the obvious) :)
So,
Using Vue.js I'm connecting to this API and want to track the history of each crypto-currencies (no issues with getting any data from the API).
Currencies information are accessible using a URL :
https://api.coinranking.com/v2/coins
And history is accessible using another :
https://api.coinranking.com/v2/coin/ID_OF_THE_COIN/history
As you can see the second url needs the id of the specific currency which is available in the first one.
I would like to find a way to make only 1 get request for all currencies and their history rather than having to make as many requests as available currencies there are (about 50 on this API), I've tried several things but none has worked yet (for instance using the coin url and storing ids of the currencies in a table then using the history url and modifying it with the ids of the table but hit a wall) .
Here's the axios get request I have for the moment for a single currency:
const proxyurl = "https://cors-anywhere.herokuapp.com/"
const coins_url = "https://api.coinranking.com/v2/coins"
const history_url = "https://api.coinranking.com/v2/coin/Qwsogvtv82FCd/history"
//COINS DATA
axios
.get(proxyurl + coins_url, {
reqHeaders
})
.then((reponseCoins) => {
// console.log(reponseCoins.data)
this.crypto = reponseCoins.data.data.coins;
})
.catch((error) => {
console.error(error)
})
//GET ALL COINS UUIDs
axios
.get(proxyurl + coins_url, {
reqHeaders
})
.then((reponseUuid) => {
this.cryptoUuidList = reponseUuid.data.data.coins;
//access to each crypto uuid:
this.cryptoUuidList.forEach(coinUuid => {
console.log("id is: " + coinUuid.uuid)
//adding uuids to table:
this.coinsUuids.push(coinUuid.uuid);
});
})
.catch((error) => {
console.error(error)
})
// COIN HISTORY/EVOLUTION COMPARISON
axios
.get(proxyurl + history_url, {
reqHeaders
})
.then((reponseHistory) => {
//get data from last element
const history = reponseHistory.data.data.history
this.lastItem = history[history.length-1]
// console.log(this.lastItem)
this.lastEvol = this.lastItem.price
// console.log(this.lastEvol)
//get data from previous element:
this.previousItem = history[history.length-2]
this.previousEvol = this.previousItem.price
})
.catch((error) => {
console.error(error)
})
I probably forgot to give some info so let me know and will gladly share if I can
cheers,
I took a look at the API, they do not seem to give a way for you to get everything you need in one request so you will have to get each coin history separately.
However, I do se a sparkline key in the returned data, with what seems to be a few of the latest prices.
I do not know your projects's specifics but maybe you could use that for your initial screen (for example a coins list), and only fetch the full history from the API when someone clicks to see the details of a coin.
Good evening everyone,
I have been making a kind of social network as a personal project using vuejs, nodejs and mysql database.
Basically, you can post a message, and then people can answer to it. I bind comments to post using an id. I got two tables: 1 comments and 1 posts. If a comment is posted for post number 38, in mysql table there is a field idPost = 38.
i got a function displaying all the answers for the post by clicking on a button, which is:
displayAnswers(id) {
axios.get('http://localhost:3000/wall/answer/get/'+id )
.then(response => {
this.answers = response.data.resultat;
})
.catch(error => {
console.log(error);
})
}
Where id is the id of the post I want to display answers.
Now, the problem is when I add a comment, I need either to refresh the page to see the comment or to force the refresh by calling the displaypost function, like this:
postAnswer(id) {
let syntaxe = /^[a-z A-ZáàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒ0-9-]{1,}$/;
if(syntaxe.test(this.answerToPost)) {
let answer = {
message: this.answerToPost,
postId: id,
auteur: this.$store.state.pseudoUser
}
axios.post('http://localhost:3000/wall/post/answer', answer)
.then(response => {
console.log(response);
this.feedbackMessage = response.data.message;
this.isAlert = false;
this.answerToPost = '';
setTimeout(() => {
this.feedbackMessage = ''
}, 2000);
this.displayAnswers(id);
})
.catch(error => {
console.log(error);
this.feedbackMessage = error.response.data.message;
this.isAlert = true;
})
} else {
this.errorMessage = "Le message ne respecte pas la syntaxe autorisée";
return;
}
},
To summarize, my data this.answers, is not reactive. it is declared this way in the app:
data() {
return {
Auteur: '',
displayPostAnswers: [],
answerToPost: '',
isAlert: true,
feedbackMessage: '',
answers: ''
}
},
and called this way in my template, using a v-for loop to display the answers:
<div v-for="answer in answers" :key="answer.id" class="answerDisplayer" >
<div class="containerEachAnswer">
<div class="avatarAuteur">
<img src="../assets/defaultUser.png" width="48" height="48" alt="">
</div>
<div class="answer">
<span>
<strong>{{ answer.auteur }}</strong><br>
{{ answer.message}}
</span>
</div>
</div>
</div>
</div>
I looked for the issue on the internet, I found this doc: https://fr.vuejs.org/v2/guide/reactivity.html.
So I tried to use the function Vue.set but it does not seem to work.
I would like to know if more experienced developer could help me to find another way to either make my data reactive or help me to do it another way, I tried several kind of things but it did not work.
PS: I tried to use computed data, but v-for does not work with computed data.
Thank you!
Have a good evening!
Since you are trying to change this within the instance I suggest you try this.$set(this.someObject, 'b', 2) as described in https://fr.vuejs.org/v2/guide/reactivity.html#Pour-les-objects
Also you seem to declare answers as a string in your data function, try declaring it as an array answers: []
I have a data table in Vuetify that is populated via a REST get request, using a function "getData" that is called when the app is mounted. The <td>'s in the table have buttons that the user can hit to "lock" the period (the row/column intersection).
When they hit the button, they get a popup confirmation dialog. When they hit "OK", there is a save method called to write the current date back to the db via a REST PATCH request (see below).
My problem is, the grid is not updating with the results of the patch request. I have to manually refresh the page to see the result. What is the common pattern here? Should i pull down the data again via getData to refresh the table? Should i update the array that the data-table sits on directly?
getData method:
getData() {
var self = this;
return axios
.get("http://127.0.0.1:5000/api/estimatefinal/periods?dataset=capital")
.then(function(response) {
self.periods = response.data;
})
.catch(function(error) {
alert(error);
});
},
Save method:
save(item) {
var self = this;
axios
.patch("http://localhost:5000/api/estimatefinal/period/" + self.id, {
date: moment(self.selected_date, "YYYY-MM-DD").format(
"YYYY-MM-DDTH:m:s"
)
})
.then(function() {
this.getData(); // ????
})
.catch(function(error) {
alert(error)
});
this.getData(); // ????
this.close();
}
If your PATCH changes only one row in DB, means has visually effect on only one row on your v-data-table, then you can change the data locally when you get "success" response from back-end.
If, in other hand, your PATCH changes many other things in DB (also in v-data-table) your best option is probably to getData() after you get PATCH response.
Point is to keep that same "picture" of values in DB and on screen v-data-table.
I have a such HTML code.
<div id ='pages'>
<div id='wrapper'>1 </div>
<div id='wrapper'>2 </div>
</div>
I am want to find elements count with id wrapper.
I using Cypress. I'm starting to learn Cypress.
If I try:
cy.get('div#wrapper').should('have.length', 2)
I get AssertionError:
CypressError: Timed out retrying: expected 1 to equal 2
As jonrsharpe pointed out, it's invalid HTML to have multiple elements with identical id attribute.
That being said, DOM is quite smart and can recover and work even with invalid HTML. Duplicate-id elements shouldn't cause much trouble.
If you e.g. try doing document.querySelectorAll('#wrapper') it should return list of 2 elements (in your case).
Problem is, Cypress is using jQuery to query the DOM instead of using native DOM methods and I guess jQuery isn't as smart (or it's more pedantic).
That being said, I can't reproduce that error when running:
// succeeds
cy.get('div#wrapper').should('have.length', 2)
Only when querying #wrapper directly (without the preceding div):
// fails
cy.get('#wrapper').should('have.length', 2)
I reckon this is because jQuery uses a heuristic of exiting early when a selector string (#wrapper) contains only a single id (and that's why div#wrapper returns both elements).
Also, your solution in comments (cy.get('#pages') .find('div#wrapper') .should(($div) => { expect($div).to.have.length(2) })), while working, isn't ideal because it won't retry. Let me demonstrate:
In the following code, the 2nd #wrapper will appear in the DOM only after 1 sec.
describe( 'test', () => {
beforeEach(() => {
cy.document().then( doc => {
doc.body.innerHTML = `
<div id='pages'>
<div id='wrapper'>1</div>
</div>
`;
setTimeout(() => {
doc.body.innerHTML = `
<div id='pages'>
<div id='wrapper'>1</div>
<div id='wrapper'>2</div>
</div>
`;
}, 1000 );
});
});
// will fail
it('solution A', () => {
cy.get('#pages') // <- won't be retried
.find('div#wrapper') // <- only this command will be retried
.should( $div => expect($div).to.have.length(2) );
});
// will pass
it('solution B', () => {
cy.get('#pages #wrapper') // <- will be retried and succeed in 1sec
.should( $div => {
expect($div).to.have.length(2);
});
});
// will pass
it('solution C', () => {
cy.get('#pages')
.should($pages => {
// using native DOM querying
expect($pages[0].querySelectorAll('#wrapper').length).to.eq(2);
});
});
});
Thus, you should go with solution similar to B or C.