ReactJS get token string from API fetch - javascript

I set up an API in Java. But now I'm developping a client in ReactJS. The authentication uses a JWT Token. With Postman, when I send a POST request to the authentication URL, it returns me a JWT token like this :
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZHVzZXIiOjEsImlzcyI6ImF1dGgwIn0.0BXAQl-yMIDeAU6Emppo6LBIm1RAdLa9vDWbQkdLs1o
That's exactly what I want. But I don't know how to retrieve a string after a fetch call in ReactJS.
I tried to use the promises and wrote this :
.then((data) => {
data.text().then((token) => {
alert(token)
})
})
But it returns me nothing, I have an alert with no text.
How to get String from the Object Response returned by the fetch ?

Maybe you back end server return Content-Type=application/json? Instead text() method try using json().
Try this:
fetch('/next/page')
.then(function(response) {
return response.text();
})
.then(function(text) {
// <!DOCTYPE ....
console.log(text);
});

I was facing the same issue and was able to get the token with this:
.then(res => res.json()).then(res => {
let token = res.token;
console.log("token: ", token);
});
Source:
https://developer.mozilla.org/en-US/docs/Web/API/Body

The text() method on that response object is what you are looking for.
Using await syntax I think is a bit simpler than using then() With await, this in this.setState() is scoped as expected.
async getStrResponse() {
const response = await fetch('myController/GetStringTest');
const stringResponse = await response.text();
this.setState({ someStr: stringResponse, loading: false });
}

Related

NEXTJS - fetching data from the server

I want to fetch data from the nextjs server on the front end, however the code after fetch() doesn't work in the onSubmit() function.
here is the /test page
pages/test
const onSubmit = (data) => {
console.log("________");
users.map(async (user, index) => {
if (data.email === user.email) {
if (data.password === user.password) {
console.log("hi");
const data = await fetch("http://localhost:3000/api/test");
// after the fetch, this code does not run
console.log("back-end is: ", data);
}
}
});
};
and here is my code in /api/test
export default async function student_method(req, res) {
return console.log("get in server");
}
so please what is the problem??
i'm try to get the data inside the database
so we need to use fetch() method but fetch() work succesfully but code after fetch() does not work
I think the issue is using the return statement on the server side. NextJS provides helper methods in the res object you receive in your server-side function.
Try something like this:
res.status(200).send("get in server");
For details, see here: API Routes: Response Helpers
const data = await fetch("http://localhost:3000/api/test");
The problem is that line. There you waiting a Promise resolve, but if you see you api/test you only return a log.
Please try returning a Promise.
The code is not working now because you're waiting for the server response but you aren't sending anything from the server.
You should send response to the client like this:
export default async function student_method(req, res) {
/* status code 200 or any other status codes */
res.status(200).send("get in server");
}

Is it good practice to access req.query in a PUT request?

I'm building a website with an API using NEXTjs. For a single element, I use the dynamic api route provided by NEXTjs and I'm currently using that route both for getting an element and updating element.
In both the GET and PUT request, I use the req.query.fetchId to get or update the element.
However, I see req.query mostly used for GET requests and in POST/PUT request it's usually req.body being used.
It seems to work, but I'm wondering if I should?
This is the URL for the request: api/items/[fetchId]
And this is my code for the PUT request so far:
if (req.method==="PUT") {
try {
const { db } = await connectToDatabase();
const videoGamesCollection = db.collection("videogames");
const result = await videoGamesCollection
.updateOne({ _id: ObjectId(req.query.fetchId) }, {$inc: {}})
res.status(200).json({ message: "success", result: result });
} catch (error) {
res.status(error.code ?? 502).send({
message: error.message ?? "Something went wrong.",
});
}
}

Cypress - get value from json response body

I'm using Cypress to do some API testing, but I am struggling to access values in the JSON response body; however I can perform assertions against the body which suggests it's receiving it correctly.
Below I am trying to assign the JSON body (response.body) and then get the value of 'id' out of it:
describe('Creating a board', () => {
it('should create a board', () => {
cy.request({
method : 'POST',
url:`${requestUrl}/boards/`,
qs: {
name : "test-board",
token : token,
key : key
}
}).then((response) => {
expect(response).property('status').to.equal(200)
expect(response.body).property('id').to.not.be.oneOf([null, ""])
const body = (response.body)
boardId = body['id']
})
})
I've done numerous searches and can't find a concrete way to do it. Any help would be appreciated...
I managed to solve this by using a Promise;
Doing some further reading, I found out the then function I am executing is synchronous (I'm new to JS, pls don't hurt me).
I refactored the then function to the following:
.then((response) => {
return new Promise(resolve => {
expect(response).property('status').to.equal(200)
expect(response.body).property('id').to.not.be.oneOf([null, ""])
const respBody = response.body;
boardId = respBody['id']
resolve(boardId)
})
It's probably not entirely correct or best practice, but it will do for my demo
Although not needed anymore as you found a workaround, I've looked into my cypress code. I was able to access properties of response body followingly:
cy.request({
...
}.its('body').then((body) => {
const whatever = body.whatever;
})
I believe it basically works the same as your workaround - waiting to resolve body in a promise.
I was able to do it in the following way:
cy.request(
'POST',
url,
payload()).then((response) => {
expect(response.body).to.have.property('ReturnCode', 'Success')
expect(response.body).to.have.property('ReturnText', 'Success')
expect(response.body).to.have.property('PaymentInstructionId')
paymentID = response.body.PaymentInstructionId
})
paymentID is the variable that is filled with the value that i want from the repply.

How to get a correct response from an API on AWS lambda

This is my first time soliciting the Stack-Overflow community.
Since a few days I have been learning to use the AWS lambda service connected with GETEWAY.
I need to do a GET on an API but the problem is that I constantly receive a empty response.
Here is an example of my code with a free access API:
var getApi= async function(event) {
var x = await axios.get(url)
}
var getResponse = async function(){
var data= await getApi()
if (data.status ==200){
return data
}
}
exports.handler = async function() {
return getResponse().then(res => {
const response = {
statusCode: 200,
body: JSON.stringify(res),
};
return response
}).catch(error => { return error})
};
Thank you very much for your help,
It is because of node.js asynchronous call.
Your function finishes the running before asynchronous call returns.
I fixed some lines of codes. I wish this might be helpful for you.
const getApi= async function() {
return await axios.get(url)
}
const getResponse = async function(){
const data= await getApi()
if (data.status ==200){
return data
}
}
exports.handler = async function() {
return await getResponse().then(res => {
const response = {
statusCode: 200,
body: JSON.stringify(res),
}
return response
}).catch(error => console.error(error))
}
I would suggest using console.log() all over the file to debug. You should by default be able to see the response to these console logs in Cloudwatch :)
Read more here:
https://docs.aws.amazon.com/lambda/latest/dg/monitoring-functions-logs.html
I myself ran into this issue very recently. The solution is:
If you are using the Lambda as an authorizer in your AWS Gateway, then the Lambda should return a JSON object that contains principalId, policyDocument and context.
Context is a map where you can add your own custom variables such as Strings, Numbers and Booleans.
The entire content of the JSON object will be returned to the Gateway. Check out this documentation: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html
I also have a pretty detailed Stackoverflow post on how the Gateway should be configured via Cloudformation YAML file: AWS API Gateway with Lambda Authorizer

Get request yields response with data in it, but when accessing .data specifically it yields undefined

Apologies if the terminology is not great, still new to fullstack.
Hello! I am trying to get all the users in my DB. The get() response is OK as the client is receiving the response (see image below)
The problem is that when I try to fetch the .data I get undefined.
Here's my Vue Component
import UserService from '#/services/UsersService.js'
export default {
data () {
return {
users: null
}
},
async mounted () {
// GET request for all users.
this.users = UserService.index().data
console.log('The response is OK', await UserService.index())
console.log('when trying to fetch the .data I am getting ', await this.users)
}
}
The index() function
import Api from '#/services/Api'
export default {
index () {
return Api().get('users')
}
}
Everything works fine, except that I get undefined data...
I think you forgot to fetch the data asynchronously?
async mounted () {
// GET request for all users.
- this.users = UserService.index().data
+ const res = await UserService.index()
+ this.users = res.data
console.log('The response is OK', await UserService.index())
console.log('when trying to fetch the .data I am getting ', await this.users)
}
You correctly use await syntax in the first console.log, which might explain why the data return correctly.

Categories

Resources