I encountered a problem using next.js in the api routes. Here is the code in question:
////////
schema
////////
model Movie {
id Int #id #unique #default(autoincrement())
title String
year Int
}
///////
fetch request
///////
async function handleSubmit(e) {
e.preventDefault();
onSubmit({
id: Math.floor(Math.random() * 10000),
title: formData.title,
year: formData.year
});
const response = await fetch('/api/movie/[id]', {
method: 'PUT',
body: JSON.stringify(formData)
})
return await response.json()
}
//////
[id].js
//////
export default async({query: { id }, movies}, req, res) => {
const data = JSON.parse(req.body)
const updateMovie = await prisma.movie.update({
where: {
id: parseInt(id)
},
data
})
res.json(updateMovie)
}
export async function getServerSideProps() {
const movies = await prisma.movie.findMany()
return {
props: {
data: movies
}
}
}
Obviously, this code will update the data with an ID of “1”. But what if I wanted to update data with the ID of “4”? How would I do this without having to manually go in the code and change the ID every time?
I have tried putting this variable where the ID is:
const movieId = movies.map((movie) => movie.id === id)
but I get this error every time:
'SyntaxError: Unexpected token u in JSON at position 0'
I don't know what else to do? Any help would be appreciated!
Related
Sorry for such noob question but I'm a simply gave up. I've got below code which creates a POST request to the BE part of the app - user provides input (productCodes) and push submit button. That part works well, Vue sends request to BE but in the response FE should have received JSON with result: { id: 1234 }
How do I get this response and display it inside the app? I've got below:
imports.js
const createProductsRequest = (self, products) => {
const jwtToken = self.$store.state.idToken;
const payload = JSON.stringify({ product_codes: products['product_codes'].split(',') })
return axios
.post(`/api/v1/imports/products/`, payload,{
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(response => response.data)
};
export {
createProductsRequest
};
sync_product.vue
<script>
import {
createProductsRequest
} from '../../api/imports'
import ModalController from '../general/modal_controller'
export default {
name: 'BackboneSyncProducts',
data() {
return {
styleCodes: [],
}
},
computed: {
productsToSyncAmount () {
return this.styleCodes.length
},
},
methods: {
async syncProducts() {
let confirmationText = `Do you want to ${this.productsToSyncAmount} sync products?`
if (this.productsToSyncAmount === 0) {
ModalController.showToast('', 'Type product codes for sync first, please!', 'warning')
}
else if (await ModalController.showConfirmation('Confirmation', confirmationText)) {
try {
ModalController.showLoader()
await createProductsRequest(this, this.styleCodes)
const successMessage = `${this.productsToSyncAmount} products have been queued for sync`
await ModalController.showToast('', successMessage)
} catch (data) {
const errorMessage = `Error occurred during queueing products to sync - `
ModalController.showToast('', errorMessage + data?.message, 'error')
} finally {
this.styleCodes = []
ModalController.hideLoader()
}
}
},
}
}
</script>
That's all what I have.
Instead of calling your request without getting the return value:
await createProductsRequest(this, this.styleCodes)
You can get the return value which is the result of the request :
const data = await createProductsRequest(this, this.styleCodes)
By doing that, data must contain the result of the request, as you mentionned { id: 1234 }.
--
If you want to use this result in your component, you can create a reactive value in data()
data() {
return {
styleCodes: [],
data: null
}
},
And store the result like this :
this.data = await createProductsRequest(this, this.styleCodes)
With that you can display it in your template for example :
<template>
<!-- There is a v-if because before doing the request, data is null -->
<div v-if="data">{{ data.id }}</div>
</template>
So I have getStaticProps and need to do some data fetching based on a variable here is an example
export async function getStaticProps() {
const res = await fetch(localWordpressUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query: `
query AllPostsQuery {
posts(where: {categoryName: "blog"}) {
nodes {
slug
content
title
}
}
}
`,
})
});
const json = await res.json();
return {
props: {
posts: json.data.posts,
}
};
}
Where categoryName: "blog" needs to be a variable instead of hard coded. I know you can get the slug, but what I need is before the slug. i.e. site.com/blog/slug. Any suggestions on this?
You're actually really close. What you need is to grab the context out of your getStaticProps function. Add this to your getStaticProps function, and look at the console log to see what's happening.
export async function getStaticProps(context) {
console.log(JSON.stringify(context, null, 3));
const { asPath, req, res, pathname, query } = context;
if (req) {
let localWordpressURL = req.headers.host;
console.log(localWordpressURL);
}
}
My postman request :
{
"content": "my content",
"likes": 0
}
Response in postman :
{
null
}
Here is my code:
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Post extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
models.Post.belongsTo(models.User, {
foreignKey: {
allowNull: false,
name: "userId"
}
})
}
};
Post.init({
content: DataTypes.STRING,
comments: DataTypes.STRING,
attachment: DataTypes.STRING,
likes: DataTypes.INTEGER
}, {
sequelize,
modelName: 'Post',
});
return Post;
};
controllers :
module.exports.createPost = async (req, res, next) => {
const token = req.cookies.jwt;
const decoded = jwtAuth.verify(token, process.env.TOKEN_SECRET);
console.log(decoded);
const userIdFound = await User.findByPk(decoded.id);
I can't get the user id despite the request it returns a null value :
try {
const { body } = req;
console.log(body);
await User.findOne({ where: { id: userIdFound } })
.then((userFound) => {
//Create a Post if User Id is valid
if (userFound) {
const newPost = Post.create(
{ ...body, userId }
).then(() => res.status(201).json(newPost))
.catch(err => res.status(404).json('Unauthorizated request !'))
}})
Les erreurs :
} catch (err) {
throw new Error(err);
}
}
thank you very much for your help (I'm still a beginner, there will surely be some mistakes).
I don't understand from where you "pushing" the userIdFound on your where clause in the querie.
But I think you can try to insert the value id in a const, and use him on the where. Supposing the id field name in your HTML sending the post or get request is "id", you can insert it like this:
const userIdFound = req.body.id;
await User.findOne({ where: { id: userIdFound } })
//Some code for the logic
You can see more in the documentation here
today I had some problems with my code.. the thing is I have to create a multiple POST request to the API to pass users to a group, so.. the API request is:
POST /users/user-group-membership
{
"userId": "string",
"groupId": 0,
"isActive": true,
}
Basically i have to grab from the users table the userId from each user and for each userId create a multiple request... so what i did was:
const moveTogroup = async (
token: string,
userId: string,
groupId: number,
): Promise<any> => {
const res = await axios({
method: 'POST',
url: `${API}/users/user-group-membership`,
data: { userId: userId, groupId: groupId },
headers: {
Authorization: `Bearer ${token}`,
},
});
const { data } = res;
return data;
};
export const moveAllGroup = (
token: string,
): ThunkAction<void, State, null, UsersActions> => {
return async (dispatch, getState) => {
const { userId, groupId } = getState().FleetUsers;
const convert = userId.toString();
console.log(convert);
dispatch(moveUserToGroupRequest());
try {
const userPromises = userId.map(() =>
moveTogroup(token, convert, groupId),
);
const move = await Promise.all(userPromises);
console.log('moving:', move);
dispatch(moveUserToGroupSuccess(move));
Swal.fire('Saved', 'Your Changes has been saved', 'success');
} catch (error) {
dispatch(moveUserToGroupFailure(error));
Swal.fire('Error', error, 'error');
}
};
};
But as you see this only works for one userId, I grabbing from the state the userId and the groupId, converting the userId to string, and voila is working perfectly, only what I want is depending how much userId I have in the state replied to the request for creating multiple requests and when the user selects in table 2 or 3 users, he or she can move them easily.
If your userId var contains all userIds, you must map it to recover specific information about each userId :
userId.map((elt) => {
const convert = elt.toString();
moveTogroup(token, convert, groupId),
});
I am trying to return the response object i get from stripe after creating a subscription using npm.
import Stripe from 'stripe';
const key = require("stripe")("XXXXXXXXXXXXXXXXX");
export function subscribe(cus, items) {
key.subscriptions.create({
customer: cus,
items: items
});
}
When I used fetch (POST) i used to do this:
if (response.status >= 200 && response.status < 300) {
// transaction successful - get charge ID
const ret = await response.json();
let subId = ret.id
return {"subId": subId};
}
// transaction failed - return error messages and codes
let res = await response.json();
let err = res.error.message;
let code = res.error.code;
let type = res.error.type;
return {"error": err, "code": code, "type": type};
}
But in node i don't understand. I need to return the entire response so that I can store the subscription id, customer id ,etc.
I tried using this but does not work even though the subscription is successful
key.subscriptions.create({
customer: cus,
items: items
}, function(err, subscription) {
if (err) {
let response = err;
return{response};
}
let response = subscription;
return{response};
}
}
);
Here is an example from Stripe API Documentation
inside Call back function you will get desired Output
var stripe = require("stripe")("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
app.post('/stripe/sub', (req, res) => {
stripe.subscriptions.create({
customer: "cus_EcmCu9HT7EZWEH",
items: [
{
plan: "emerald-company-234",
},
]
}, function(err, subscription) {
if(subscription){
res.send(subscription)
}
}
);
});