How to get myshopify custom page content from server - javascript

I have created the my custom page called "pages.api.main-menu.liquid"
When I access page from preview mode it shows the the content.
The case is I want to take the content of this page from Next Server. So I sent a request directly to this page.
export default (req, res) => {
const {
SHOPIFY_STORE_URL,
SHOPIFY_ADMIN_API_KEY,
SHOPIFY_ADMIN_API_PASSWORD
} = process.env
serverCoreAPI
.get(
`https://${SHOPIFY_ADMIN_API_KEY}:${SHOPIFY_ADMIN_API_PASSWORD}#${SHOPIFY_STORE_URL}/pages/main-menu-api`
)
.then((response) => {
console.log(response)
res.status(200).send(response.data || { data: null })
})
.catch((e) => {
console.log(e)
})
}
I am taking as a response the error code 400.
Anyone can help with this?

Related

400 bad request with ReactJs

I'm trying to make a post request to the server,but it returns 400 error.
:
this is react function
const handleSubmit = () => {
const bookInstanceObject = {
imprint: imprint,
};
axios
.post('http://localhost:3001/catalog/bookinstance/create', bookInstanceObject)
.then(res => {
console.log(res.data);
})
.catch(error => {
console.log(error);
});
};
and this is the server side:
router.post('/bookinstance/create', (request, response, next) => {
const body = request.body;
const bookInstance = new BookInstance({
imprint: body.title,
});
bookInstance
.save()
.then(savedBook => {
response.json(savedBook.toJSON());
})
.catch(error => next(error));
});
any idea ?
What I think is happening
The front end's handleSubmit function is POSTing to /catalog/bookinstance/create, while the server is expecting it to come to /bookinstance/create.
Simple typo, easy to miss when your stressing over it not working.
How to fix?
Change the URLs to match.
Either:
change the front-end's POST url to /bookinstance/create,
or:
change the server's expected route to router.post('/catalog/bookinstance/create',
Why is it a GET in the error log?
I don't know but I suspect that this error is about a GET request somewhere else in your code.
Please let us know in the comments if the error goes away with this fix. (Assuming my fix works)

not able to send request to express server using axios

I am building a chat application like whatsapp, & implementing the feature - when user clicks on any person's name, his chats appears, but can't able to send request to server when user clicks
Source code
There is div, when user will click on it, it will fetch data from server (onclick event handler) in Sidebar.js file -
{friends.map((e) => (
<div
onClick={getChatDetails}
key={e.friendName}
className='sidebar_chat_info'>
<Avatar />
<div>
<h2>{e.friendName}</h2>
<p>{getLastMessage()}</p>
</div>
</div>
))}
this is getChatDetails function in sidebar.js file
const getChatDetails = (e) => {
//console.log(e.target.textContent);
const Myfriend = e.target.textContent;
axios
.post('http://localhost:2000/message/get', { friend: Myfriend })
.then((response) => {
console.log(response);
})
.catch((error) => console.log(error));
};
At the server side , this is route in index.js file
Server is running on port 2000
app.post('/message/get', isloggedIn, async (req, res) => {
console.log('REQUESTED!');
try {
const conversation = await req.user.MyConversation.find(
(element) => element.friendName == req.body.friend
);
const messages = await conversationModel.findById(conversation.chats);
res.send(messages);
//await MessageModel.remove({})
} catch (error) {
res.status(500).send(error);
}
});
This is error on browser console , when I am clicking on div
But when I am sending request through postman, I am getting response
When I am sending request in other files (login.js), it's working there, don't know why it is not working only Sidebar.js file
The issue that you're having is that e in getChatDetails is undefined. The reason for this is is onclick does not pass an event object. In order to pass an event object to your sidebar function, you need to attach an event listener to it, which is a bit better than using onclick in most cases anyways (imo). Something like this:
const sidebar = document.getElementsByClassName('sidebar_chat_info')
for (let i = 0; i < sidebar.length; i++) {
sidebar[i].addEventListener('click', handleClick = e => {
//console.log(e.target.textContent);
const Myfriend = e.target.textContent;
axios
.post('http://localhost:2000/message/get', { friend: Myfriend })
.then((response) => {
console.log(response);
})
.catch((error) => console.log(error));
})
The middleware "isLoggedIn" causing issue. The problem was in my authentication part, when the user has been logged in then only he will see home page
index.js file at line 113
I added console.log and found that "NOT LOGGED IN " is displayed
function isloggedIn(req, res, next) {
if (req.isAuthenticated()) {
return next();
} else {
console.log('NOT LOGGED IN !');
res.status(500).send('DENIED PERMISSION!');
}
}
I think it is happening because after logging in , I am redirecting to home page from
Login.js at line 59
history.push('/', { user: response.data });
const submitForm = async (e) => {
e.preventDefault();
axios
.post('http://localhost:2000/login', {
username: username,
password: password,
})
.then((response) => {
history.push('/', { user: response.data });
})
.catch((error) => setIsError(true));
//console.log(user.data); //user.data contains the details
//CALLING THE HOME PAGE AFTER SIGNUP & SENDING DETAILS OF CURRENT USER THERE !
//history.push('/', { user: user.data });
};
Maybe the request will be authenticated only from Login.js file, but I can't make other request from this file like getting chats details, sending message etc. I will have to go to home page . That's why I am redirecting to home page after logging in
On home page my request is not authenticated.
In postman all routes are working as I am not switching pages.
Login and logout routes are working as they are not taking in account "isLoggedIn"
Please suggest how to work with routes that needs authentication, like send message, gettingchats details?
PS - My request is even not authenticated from Login.js. After logging in, this time I didn't redirect to home page. I made request to route that needs authentication after logging in , it's still showing "NOT LOGGED IN" on server

How to globally activate useEffect in React?

I am creating a chat application in React. I am using the useEffect-hook to update the messages (all it really does is fetch them from the JSON-server). I want them to be updated every time someone in the room sends a new message.
This is one alternative I have:
useEffect(() => {
fetch('http://localhost:8000/messages/')
.then(res => {
return res.json();
})
.then(data => {
data = data.filter((msg) => msg.room === room);
setData(data);
})
.catch(err => {
console.error(`Error: ${err}`);
})
divRef.current.scrollIntoView({ behavior: 'smooth' });
}, []);
"data" is a list of messages. This shows all the messages when you enter the room, but does not load when you pass a new message. Assumingly because of the empty list at the end. Therefore I tried this:
In another component, I have a variable "sent", which is set to true every time you send a message, like this:
const onSubmit = (e) => {
e.preventDefault();
const data = {author: user, body: msg, room }
setSent(true);
fetch(`http://localhost:8000/messages/`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
})
.then(response => {
response.json();
setSent(false);
})
.catch(err => console.error(`Error: ${err}`));
setMsg('');
}
So every time you send a message, it is set to 'true', and as soon as it has been successfully sent, it is set back to 'false'. I then passed it as a prop to the component I use useEffect:
<div className='chat-main'>
<Messages user={user} room={room} sent={sent} />
</div>
Then I put the "sent"-variable in the list at the bottom of the useEffect-hook. This updates the messages for the user who sends a message, but not for the others (because, of course, "sent" only changes if you send a message)
What can I do here? Is there a way?

CORS Error on uploading image/video file to google cloud in react js

When user drag and drop the Image, I need to call a method of the server to get the Media_id for that particluar image/video, in the response of that I am getting this ->
MAIN RESPONSE -->>
{
"status": 1,
"media": {"media_id": 27, "media_type": 1, "media_file_name": "a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063bef4e44e1a4d83f3.png", "media_placeholder": null, "media_ext": "png"},
"upload":
{
"upload_url": "https://storage.googleapis.com/fnc-59aa2e6b-71552c9d-6441d628-951a8f6f/l.img/ori/a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063bef4e44e1a4d83f3.png?Expires=1603388214&GoogleAccessId=12345678-compute%40developer.gserviceaccount.com&Signature=UNt8nS3%2BJYiS4AuYdZ7Z2fvfDZ0fAKf8bSZbeRlHyhqxb5i6xjpqnqgR7JYp9Q3FgJItcYr%2BHDL90WiUpbMQi%2B4s0XNW683CaSoUChkRMjj1AvkH%2Be0u8%2Fw5VVIMF9j52bTFePWISTLvwQ1RlEdNPNkrpbcamTsJFyBVi89%2BIpXArsVlhvDzK55Zvj%2Fvzh00GgdNrH%2BRog8Q%2BkGITE8bW%2FxRpQ30OdMZLjpLtp%2FNg5KVotHrx6Bet7vidKymiJQ9BbwCxTRGzBdAITr2rsKTMGZJzfvEKnIczsoiY91Zmc3hjGzUD9OxHGR%2BiRdN%2F2FbotOIVR48RE%2BoAdIGIEfKlw%3D%3D",
"file_name": "a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063bef4e44e1a4d83f3.png",
"content_type": "image/png", "exp": "2020-10-22 17:36:54.447484"
}}
So, I need to hit this upload url which is coming from the response.Below is my file where I am hitting this as soon as user drop the image ->
UploadImage.js
await this.props.getFirstMediaId(postdata).then(res => {
if (res.value && res.value.status === 1) {
let media_idArr = this.state.media_id.concat(res.value.media.media_id)
this.setState({ media_id: media_idArr, mediaUrl: res.value.upload })
customStatus = 'done';
}
}) //First call to the server to get Media_id and the cloud **upload URL**
***** FOR THIS API RESPONSE, PLEASE SEE THE ABOVE MAIN RESPONSE *****
const getUploadParams = () => {
console.log(this.state.mediaUrl, ' -->>> this.state.mediaUrl')
if (this.state.mediaUrl !== null) {
console.log(' in get upload param.')
return this.props.postImageToCloud(this.state.mediaUrl).then(res => {
console.log(res, '===>> here is cloud res.')
})
.catch(err => {
console.log(' here is error cloud -->>> ', err)
})
}
}
Below is the file where the method actually call API ->
service.js
export const getFirstMediaId = (data) => {
return {
type: GET_FIRST_LISTING_MEDIA,
async payload() {
let response = await callAxios.post(SUBMIT_LISTING_FIRST_MEDIA, data);
return objectPath.get(response, 'data', []);
}
}
}
export const postImageToCloud = (url) => {
return {
type: PUT_MEDIA_TO_CLOUD,
async payload() {
let response = await axios.put(url.upload_url, {}, {
headers: {
'Content-Type': `${url.content_type}`
}
})
return objectPath.get(response, 'data', []);
}
}
}
So, the first call is success and I got the above MAIN RESPONSE but as soon as it completes, I call the cloud PUT request and got this CORS error ->
Access to XMLHttpRequest at 'https://storage.googleapis.com/fnc-59aa2e6b-71552c9d-6441d628-951a8f6f/l.img/ori/a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063bef4e44e1a4d83f3.png?Expires=1603388214&GoogleAccessId=123456789-compute%40developer.gserviceaccount.com&Signature=UNt8nS3%2BJYiS4AuYdZ7Z2fvfDZ0fAKf8bSZbeRlHyhqxb5i6xjpqnqgR7JYp9Q3FgJItcYr%2BHDL90WiUpbMQi%2B4s0XNW683CaSoUChkRMjj1AvkH%2Be0u8%2Fw5VVIMF9j52bTFePWISTLvwQ1RlEdNPNkrpbcamTsJFyBVi89%2BIpXArsVlhvDzK55Zvj%2Fvzh00GgdNrH%2BRog8Q%2BkGITE8bW%2FxRpQ30OdMZLjpLtp%2FNg5KVotHrx6Bet7vidKymiJQ9BbwCxTRGzBdAITr2rsKTMGZJzfvEKnIczsoiY91Zmc3hjGzUD9OxHGR%2BiRdN%2F2FbotOIVR48RE%2BoAdIGIEfKlw%3D%3D' from origin 'http://localhost:8000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Please suggest me anything for make it working.
Thanks.
Finally after lot of efforts I came to know that I have to pass the file in the body of PUT request, here ->
let response = await axios.put(url.upload_url, { **file here** }, {
headers: {
'Content-Type': `${url.content_type}`
}
})
But I tried passing the image file object simple the html file object using formData and passing as it is, still getting the same error. Then i started using
react-dropzone and converted the image file into the string buffer as one of the example in React-dropzone. I am going to paste here that example maybe it can help anyone. See below ->
import React, {useCallback} from 'react'
import {useDropzone} from 'react-dropzone'
function MyDropzone() {
const onDrop = useCallback((acceptedFiles) => {
acceptedFiles.forEach((file) => {
const reader = new FileReader()
reader.onabort = () => console.log('file reading was aborted')
reader.onerror = () => console.log('file reading has failed')
reader.onload = () => {
// Do whatever you want with the file contents
const binaryStr = reader.result
console.log(binaryStr)
*****PASS THIS (binaryStr) AS IN THE BODY OF PUT TO AXIOS****
}
reader.readAsArrayBuffer(file)
})
}, [])
const {getRootProps, getInputProps} = useDropzone({onDrop})
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
)
}
This is one of the Official examples of React-Dropzone, So I just pass that string buffer obj and finally It worked, no CORS issue nothing.
The Google Storage API does simply not accept requests initiated from a browser in another domain, so you won't be able to achieve this.
You should not call the API from a client but from your backend. Here is the list of the suggested libraries: https://cloud.google.com/storage/docs/reference/libraries?hl=fr
Note that JavaScript in a browser environment is not suggested (only Node.js is)

JavaScript express, node and CSVtoJSON

I'm currently developing a 'Dupe Finder' web app for a co-worker. This is my first time using the 'csvtojson' package.
I'm reading from the file just fine on the server, but when I send a response back to the client (ideally containing a json object) I'm getting this very odd console log and I'm not sure if its correct:
To get this response, I have a button on the home page, when clicked, the client makes an http request on the home directory of the server, called '/getnums'. The request reads from the CSV then should be returning and obj with its contents. It is sort of doing that, in the screenshot, if I click the tick next to promiseValue, it'll give me an array. But i'm not sure why its returning a Promise..anyway..
api.js:
var CSVDATA = () => {
fetch('/getnums')
.then(res => {
console.log(res.json())
})
}
export default {
CSVDATA,
}
'/getnums' goes to my router, which is simly router.get('/', mainController.getNums)
in the controller is where the reading begins:
const csv = require('csvtojson')
module.exports = {
getNums: (req, res, next) => {
const csvFilePath = `${__dirname}/../../client/readFrom/main.csv`
csv().fromFile(csvFilePath)
.then(jsonObj => {
return res.status(200).json(jsonObj)
})
.catch(e => {
req.error = e
next()
})
},
}
anyone have an idea what might be going on here?
That is simply how .json() works.
It returns promise so you need to handle it asynchronously
var CSVDATA = () => {
fetch('/getnums')
.then(res => res.json())
.then(json => console.log(json));
}
export default {
CSVDATA,
}
MDN link

Categories

Resources