In my vue frontend I have the following method:
methods:{
async moveToOrder() {
const res = await this.$axios.get('/product/cart-to-order', {
headers: {
Authorization: 'Bearer ' + this.userData.userToken
}
});
if (res.status === 200) {
this.$router.push({name: 'Orders'});
}
}
}
The above method hits the following method that moves the data from cart collection to orders collection in the node backend and returns the moved data from orders collection:
exports.cartToOrder = async (req, res, next) => {
///method code goes here
res.status(200).json({products: products});
}
I want to display the data that I get as response in my orders (view or route). Can I pass data returned from backend to next route in Vue ?
Or do I need to make seperate methods on frontend and backend to fetch the data from orders collection ??
You can use query or url parameters between routes with the vue router. However, the data is now exposed in the url and you will now inherit all limitations from url requirements such as length and type (url encoded string).
A couple solutions are more applicable for your issue :
As you mentioned you could trigger a subsequent request if the first call is successful.
Emit the data to the destination view/route (note that the data can only flow up or down the component tree)
(Preferred) Use a state management tool like vuex to centralize your data. You will only need to update (mutate) your data (state) once and it will be available anywhere within your application. The time investment for this solution is not negligeable, however on a longer term it can simplify your application significantly.
Related
I'm trying to pass data (array) from node.js backend to frontend JS to process it there. I don't want to pass data directly to backend-served html file because I'd like to keep it clean and don't want to do any loops there etc.
My backend part looks like this:
app.get("/search-db", function (req, res) {
const term = req.query.term;
findInDb(term);
res.redirect('/search', {
searchResults: searchResults,
});
})
async function findInDb(query) {
const collection = await getDbCollection();
await collection.find().forEach((item) => {
console.log(item.artist);
if (item.artist.includes(query) || item.name.includes(query)) {
searchResults.push(item);
}
})
}
Is this possible or do I have to clutter my html and use loop there to process passed results?
Your web page can use AJAX via fetch to make the /search-db API request to your server. Your server route handler should fetch the results from the DB, then invoke res.send() to send a JSON response back to the client, rather than res.redirect() to redirect the client to a new page.
Example: How to create a REST API with Express.js in Node.js
Also, unrelated, your findInDb function should return the search results instead of placing them in a global variable (searchResults).
I have been trying to use the Adyen Drop-in component to make payments on the Razor pages site I am developing. I have got a test version running that makes a payment for a hard-coded amount but I have yet to figure out how to pass a unique order ID to my API endpoint making the payment request.
Taking the examples from https://docs.adyen.com/online-payments/drop-in-web, the drop-in component is mounted via JavaScript using
const checkout = new AdyenCheckout(configuration);
const dropin = checkout.create('dropin').mount('#dropin-container');
where the configuration object is created with something like
const configuration = {
paymentMethodsResponse: paymentMethodsResponse, // The `/paymentMethods` response from the server.
clientKey: "YOUR_CLIENT_KEY", // Web Drop-in versions before 3.10.1 use originKey instead of clientKey.
locale: "en-US",
environment: "test",
onSubmit: (state, dropin) => {
// Your function calling your server to make the `/payments` request
makePayment(state.data)
.then(response => {
if (response.action) {
// Drop-in handles the action object from the /payments response
dropin.handleAction(response.action);
} else {
// Your function to show the final result to the shopper
showFinalResult(response);
}
})
.catch(error => {
throw Error(error);
});
},
onAdditionalDetails: (state, dropin) => {
// Your function calling your server to make a `/payments/details` request
makeDetailsCall(state.data)
.then(response => {
if (response.action) {
// Drop-in handles the action object from the /payments response
dropin.handleAction(response.action);
} else {
// Your function to show the final result to the shopper
showFinalResult(response);
}
})
.catch(error => {
throw Error(error);
});
}
};
Adyen's own JavaScript then supplies the state object for the onSubmit method, so that my API endpoint gets called with a PaymentRequest object created (somehow) from the state.data.
However, without being able to get a unique order ID into this PaymentRequest object, my server-side code does not know what amount to set. Note that one can set an Amount object in the configuration object but this is just used to display the value on the Drop-in component - the value is not passed to the server.
So how does one pass a unique order ID via the Drop-in component?
The Adyen docs don't explicitly provide an example here, but the makePayment() and makeDetailsCall() presume that you will take the state.data and post back to your server. You need to implement your own code here. At that point, you could add additional information like any identifiers.
Here is an example implementation as a reference:
async function makePayment(state_data) {
const order_id = ""; // You need to provide this however your client stores it.
const json_data = {
order_id,
state_data,
};
const res = await fetch("[url to your server's endpoint]", {
method: "POST",
body: JSON.stringify(json_data),
headers: {
"Content-Type": "application/json",
},
});
return await res.json();
}
Another helpful resource could be the Adyen node.js/express tutorial. It is more explicit on implementation details so might help remove some ambiguity.
I'm developing an app with node and react. In this app, I have created a scriptTag using the fetch function to get customer id and product id whenever a specific button is pressed. Now when I have fetched that data, I want to store it in my firebase database, which I cannot import in my script tag file because it's on the front end. Therefore, I need to send the data from my frontend to the backend of the app but I'm confused that if I use the fetch function to make POST and GET requests, what URL should I use? Moreover, can the fetch function even post the variable values or not?
Scripttag.js
const header = $('header.site-header').parent();
header.prepend('<div>Hello this is coming from the public folder </div>').css({'background-color':'orange', 'text-align': 'center'})
function addWishList(customer, productid){
/*
fetch(`url`, {
method: 'POST',
headers: {
'Content-Type': ,
"X-Shopify-Access-Token": ,
},
body:
}})
})
*/
console.log('adding item to the wishlist!!')
}
function removeWishList(){
console.log('removing item from the wishlist!!')
}
var wishbtn = document.querySelector('.wishlist-btn')
wishbtn.addEventListener('click', function(){
if(this.classList.contains('active')){ //condition to check if the button is already pressed
removeWishList();
this.classList.remove('active');
this.innerHTML = 'Add to wishlist'
}
else{
var customer = wishbtn.dataset.customer;
if(customer == null || customer == ''){
console.log('Please log in to add this item to your wishlist')
}
else{
var productid = wishbtn.dataset.product;
this.classList.add('active'); //when the user presses add to wishlist button, it add active to the button's class
this.innerHTML = 'Remove from wishlist'
addWishList(customer, productid);
}
}
})
The best way to send data from the frontend to the backend is to use the Proxy option that is provided in the Shopify Partner Dashboard.
This way you can stay in the Shopify environment since it will pass specific arguments to the request that you can check if the request is truly coming from Shopify and you will have one less worry about securing it from outside requests.
So for example you will make a fetch request to /apps/YOUR_CUSTOM_PATH and this will proxy to your URL https://example.com/custom_path where you will handle the request.
You can see more info here: https://shopify.dev/tutorials/display-data-on-an-online-store-with-an-application-proxy-app-extension
You can create a public route for your app as well that can be requested from everywhere and allow for CORS but it's usually more work to do so... so pick your poison.
Have in mind that when creating a proxy page you need to reinstall the app on the store to take effect.
PS: Don't ever use the Access Token in the frontend, that should be never present in the frontend. The AccessToken is only back-end way of communicating with the API!
I have a form in ReactJS and every time i click the submit button, the data should pass to adonis api.
ReactJs file
async handleSubmit(e) {
e.preventDefault();
console.log(JSON.stringify(this.state));
await axios({
method: 'post',
url: 'http://127.0.0.1:3333/add',
data: JSON.stringify(this.state),
})
.then(function (response) {
console.log('response',response);
})
.catch(function (error) {
console.log('error',error);
});
}
"http://127.0.0.1:3333/add" is Adonis server with a route '/add'
i don't know how to write in Adonis to post state on that route
Can anybody explain me, please?
in controller's function in get value like this
const data = request.only(['data']) then you get data.
other method to get data like this
const alldata = request.all()
this console this result and view how many result you get
and get data from this alldata.data
First, create a simple controller to handle your data which would receive from your handleSubmit() method in ReactJS app.
Use the below command to create a simple controller:
adonis make:controller TestController --type http
Once created, open the TestController file and make an index method and add the followings which are inside the index method.
'use strict'
class TestController{
// define your index method here
index ({ request }) {
const body = request.post() // get all the post data;
console.log(body) //console it to see the passed data
}
}
module.exports = TestController
After that, register your /add route in start/routes.js file.
Route.post('/add', 'TestController.index') // controller name and the method
And finally, hit the Submit button in your ReactJS app, and test it.
Most likely you be getting CORS issues when you send the request
from your ReactJS app to Adonis server, If so you have to proxy the api request to Adonis server.
To do that, open up your package.json file in ReactJS App, and add the below proxy field.
"proxy": "http://127.0.0.1:3333",
I'm very much new to Vue so please excuse my lack of knowledge here.
In one of my (child) components (Product_Collection.vue) I make an axios request to get some products from my Shopify store via their GraphQL API:
data: () => {
return {
products: null
}
},
methods: {
getProducts: function(){
// 1. axios code here...
// 2. ...then assign result to "this.products" data property
}
}
The products are displayed as thumbnails (let's say there's 10 t-shirts). I then click a product to view it in more detail with more product info and images etc (very much an Amazon-like experience).
The product is shown on it's own in a Product_Single.vue component. So far so good.
But here's the problem...
When I click back to the products page (Product_Collection.vue) (the page with the 10 t-shirts on) the axios request to the Shopify API gets called again and the component is re-rendered from scratch.
My question is how do I tell Vue to stop fetching the data from the Shopify API each time the component is rendered? Thank you
Sounds like you want cache-control, which Axios supports with an extension.
https://github.com/kuitos/axios-extensions
import axios from 'axios';
import { cacheAdapterEnhancer } from 'axios-extensions';
const http = axios.create({
baseURL: '/',
headers: { 'Cache-Control': 'no-cache' },
// cache will be enabled by default
adapter: cacheAdapterEnhancer(axios.defaults.adapter)
});
http.get('/users'); // make real http request
http.get('/users'); // use the response from the cache of previous request, without real http request made
http.get('/users', { cache: false }); // disable cache manually and the the real http request invoked
Or you could go a more complex route and cache the results yourself into an object, and check if that object exists, but then you'll have to deal with when you want to expire the data in that object.
If you use a cache-control, and cache-control headers and expiry, you can drive all that from the API layer and not have to deal with manually managed stale data in the application.
If you are not using Vue Router, and hiding the list page, you can try a simple option.
Instead of v-if, use v-show. The component will be hidden and displayed again. It won't be re-created.
Also, where do you call the API? From created or mounted hook?
If You are using GraphQL then there is the Apollo state management way which integrates nicely with graphQL. Check this out: https://dev.to/n_tepluhina/apollo-state-management-in-vue-application-8k0
So instead of rewriting the app with axios and adding vuex in the mixture, maybe Apollo client would be more convenient