invalid json with valid json (verified with online tool) - node.js

Unfortunately this was due to another unrelated part of my code. This is an invalid question. Sorry.
I am getting an invalid json response body error on my client using fetch() to a RESTFUL api.
This is my server POST code that is called by the client using this code:
.then(conn => {
conn.query("SELECT MAX(`messagesMinute`) FROM `statistics` LIMIT 1;")
.then(rows => { // rows: [ {val: 1}, meta: ... ]
var data = {
'messagesMinuteMAX': Object.values(rows[0])[0] // ugly ass code but i dont know a better way after searching for a while
}
res.json(JSON.stringify(data));
res.end();
})
This is my client code that uses fetch
// Request the highscore of messages per minute
fetch("http://localhost:3001/postRequestMinute", { method: 'GET', headers: {} })
.then((res) => {
return res.json();
})
.then(async (json) => {
console.log(json); // <<<<---- this is the log that retrieves the following
}).catch((err) => {
console.log(err);
});
The console.log that sends out the json response returns this:
{ "messagesMinuteMAX": 1341 }
This is verified as valid with multiple online json validaters.
My biggest problem with all of this is that everything works as intended, but it spits out this error anyways which is very annoying.

Maybe its your
res.json(JSON.stringify(data));
This what happend when I did in nodejs console
> a = [{ type: 'text', text: 'Hello, world1' }]
[ { type: 'text', text: 'Hello, world1' } ]
> JSON.stringify(JSON.stringify(a))
'"[{\\"type\\":\\"text\\",\\"text\\":\\"Hello, world1\\"}]"'
when you stringify 2 times you got 2 quote outside your object

After fetch API, try to use JSON.parse(object_string)
Hope it works for you
Tip: use typeof(variable) to verify variable type
let result
fetch("http://localhost:3001/postRequestMinute", { method: 'GET', headers: {} })
.then((res) => {
console.log(JSON.parse(res))
result = JSON.parse(res)
}).catch((err) => {
console.log(err);
});

Unfortunately this was due to another unrelated part of my code. This is an invalid question. Sorry.

Related

why does playwright unset shared variables after the first failure in non serial mode?

Playwright Version: 1.29.2
Operating System: Mac
Node.js version: 19.4.0
Browser: [WebKit]
Extra: vscode.
import { test, expect } from '#playwright/test';
let userToken;
test("Login", async ({ request, baseURL }) => {
const data = require('../testData.js').login_details;
const response = await request.post(`${baseURL}authenticate`, {
data: data
});
const respBody = await response.json()
console.log(respBody);
expect(response.status()).toBe(200);
userToken = respBody.data.token
});
let profileId;
test("create a new profile", async ({ request, baseURL }) => {
const response = await request.post(`${baseURL}profiles`, {
data: require('../testData.js').new_profile,
headers: {
authorization: `Bearer ${userToken}`
}
})
const respBody = await response.json()
console.log(respBody);
expect(response.status()).toBe(201);
profileId = respBody.data.id
});
test("create a post", async ({ request, baseURL }) => {
const response = await request.post(`${baseURL}posts/create`, {
data: {
text: 'foo bar'
},
headers: {
authorization: `Bearer ${userToken}`
}
})
expect(response.status()).toBe(201);
});
test("delete a profile", async ({ request, baseURL }) => {
const response = await request.delete(`${baseURL}profiles/${profileId}`, {
headers: {
authorization: `Bearer ${userToken}`
}
})
expect(response.status()).toBe(204);
});
I am trying to run cases in order but not in serial mode because I need the order to carry on with the execution of the tests regardless of failures, whilst passing shared variables between tests.
So if creating a post fails, I still need the profile to be deleted.
The happy scenario is when a test case passes it continues the execution objectively, the bad/bug scenario is:
If the 3rd case fails (create a post) then the following cases fail naturally (in this case the delete profile test).
When failure happens in the create post test, with a breakpoint in the delete profile test I check for userToken and profileId, they are both undefined at that point.
why do variables get unset with first failure and how do I avoid this or work around it?
P.s. A copy of this question is on playwright's github issues
Thank you
Serial mode is recommended for this use case: https://playwright.dev/docs/test-parallel#serial-mode
Since you mentioned not wanting to run in serial mode, you can try using fixtures to set variables and share state between tests: https://playwright.dev/docs/test-fixtures#creating-a-fixture

Weird error when trying out wit.ai's messenger bot example code

Trying to learn wit.ai and create a messenger bot via their example code from their github. after messing around and adding my own take, I encountered this error:
UnhandledPromiseRejectionWarning: Error: (#100) Param message[text]
must be a UTF-8 encoded string
I've tried using the UTF8 package (https://www.npmjs.com/package/utf8) but I don't think it resolves this issue. I believe this has also been asked years before (facebook messenger bot encoding error) but the solution provided there seemed to have been present in the original wit.ai sample code as of current yet I'm still getting the error.
This is the function where the error is thrown:
const fbMessage = (id, text) => {
const body = JSON.stringify({
recipient: { id },
message: { text },
});
const qs = 'access_token=' + encodeURIComponent(FB_PAGE_TOKEN);
return fetch('https://graph.facebook.com/me/messages?' + qs, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body,
})
.then(rsp => rsp.json())
.then(json => {
if (json.error && json.error.message) {
throw new Error(json.error.message);
}
return json;
});
};
The "v15.0/me/messages" API expects a message to either contain attachment or text.
Text:
{
"recipient": {"id": "some_valid_id"},
"message": {
"text": "some_string"
}
}
Or attachment, which expects following FB templates, which are in JSON:
{
"recipient": {"id": "some_valid_id"},
"message":{
"attachment":{
"type":"template",
"payload":{
"template_type":"generic",
"elements":[
{
"title":"example_title",
"subtitle":"example_subtitle",
"image_url":"some_url",
"buttons":[
{
"type":"postback",
"title":"Option1",
"payload":"opt1"
},
{
"type":"postback",
"title":"Option2",
"payload":"opt2"
}
]
}
]
}
}
}
}
Based on the above, it is either "text" for a simple string, or "attachment" for a rich message.
Returning back to your error. When using a value other than an encoded string for text, you will get the exact error:
UnhandledPromiseRejectionWarning: Error: (#100) Param message[text] must be a UTF-8
You will notice that this is what you are doing in your code, i.e using json with text instead of attachment.
I hope this will help fix the issue for you, but I fixed mine using what I mentioned above.

Use Open API Cdiscount to find products

I would like to be able to display different Cdiscount products from a search on my site.
I use Open API Cdiscount, however I get the impression that it doesn't always work.
On Postman, it only works in 'POST' and with Axios I don't know whether to put the parameters in a body or something else?
I'm a little lost, there is no documentation ...
Some examples, on Postman in 'POST' with my parameters, I have many results, in 'GET', the request is executed endlessly.
Axios side, I think I did my request well:
axios.get('https://api.cdiscount.com/OpenApi/json/Search', {
params: {
ApiKey: 'TOKEN',
SearchRequest: {
Keyword: 'harry potter',
Pagination: {
ItemsPerPage: 5,
PageNumber: 0
},
Filters: {
Price: {},
Navigation: 'books',
IncludeMarketPlace: true
}
}
}
})
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});

Getting 400 Bad Request When POSTing to Get Transaction Token

I'm trying to integrate our website with Converge API with Hosted Payments Page. Here is the link to their documentation https://developer.elavon.com/#/api/eb6e9106-0172-4305-bc5a-b3ebe832f823.rcosoomi/versions/5180a9f2-741b-439c-bced-5c84a822f39b.rcosoomi/documents?converge-integration-guide/book/integration_methods/../../book/integration_methods/hosted_payments.html
I'm having troubles getting past the first step which is requesting a transaction token from their API endpoint. I'm sending a POST request from my server using axios with the correct parameters and URL, but when I try and POST i get 400 Bad Request. When I make the same request in POSTMAN I get a 200 response with the transaction token. I talked to their developers and they said that everything I was doing was correct and that nothing seemed odd within my code, so even they were stumped as to why I couldn't make a POST request to their endpoint. Obviously there is something within my code that their API is not liking, or else I wouldn't be here trying to find answers for this.
Here is how I'm making the POST request:
app.get('/converge_token_req', (request, response) => {
let params = {
ssl_merchant_id: '*****',
ssl_user_id: '*****',
ssl_pin: '*****',
ssl_transaction_type: 'ccsale',
ssl_amount: '1.00'
}
axios.post('https://api.demo.convergepay.com/hosted-payments/transaction_token', params, {
headers: { 'Content_Type' : 'application/x-www-form-urlencoded' }
}).then((res) => {
response.send(res.data)
}).catch((error) => {
console.log('there was an error getting transaction token')
response.send(error.message)
})
})
Here are the Request Headers:
I'm honestly out of ideas to try. The developers say that everything looks just fine yet I'm unable to make a successful request to their API. If anyone has any thoughts on this that would be great. Thanks!
This code below worked for me:
app.get('/converge_token_req', (request, response) => {
let params = {
ssl_merchant_id: '*****',
ssl_user_id: '*****',
ssl_pin: '*****',
ssl_transaction_type: 'ccsale',
ssl_amount: '1.00'
}
axios({
method: 'post',
url: 'https://api.demo.convergepay.com/hosted-payments/transaction_token',
params: params
}).then((res) => { response.send(res.data)
}).catch((error) => {
console.log('there was an error getting transaction token: ',
error)
})
})
I've since found out the solution to my problem. The issue here is that converge expects a x-www-form-urlencoded string that needs to be Stringified before submitting the request. I found a library that works well for this called qs and I used it like so:
let params = qs.stringify({ // need this if content_type is application/x-www-form-urlencoded
ssl_merchant_id: env.CONVERGE.MERCHANT_ID,
ssl_user_id: env.CONVERGE.USER_ID,
ssl_pin: env.CONVERGE.PIN,
ssl_transaction_type: request.query.type,
ssl_amount: request.query.amount,
ssl_email: request.query.email,
ssl_company: request.query.company,
ssl_avs_address: request.query.address,
ssl_avs_zip: request.query.zip,
ssl_description: request.query.desc,
})
axios.post('https://api.convergepay.com/hosted-payments/transaction_token', params, {
headers: {
'Content_Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).then((res) => {
response.send(res.data)
}).catch((error) => {
console.log('there was an error getting transaction token')
response.send(error.message)
})
I think you could also get away with just using JSON.stringify() but this way worked for me.

Cypress : how to forward response body JSON to be used on headers

i'm gonna test REST API using Cypress.io , but using chaining request, it wants to be work like this, JSON response body on the first API will be used on the next API Headers for Authorization
I'm already try doing by using cypress commands and printing on console.log, but seems like it does not captured on the log, or is there any clue for this, or i just using another command like cy.route ?
Cypress.Commands.add("session", () => {
return cy.request({
method: 'POST',
url: '/auth/',
headers: {
'Content-Type': 'application/json',
},
body: {
"client_secret" : ""+config.clientSecret_staging,
"username": ""+config.email_staging,
"password": ""+config.password_staging
}
}).then(response => {
const target = (response.body)
})
})
it('GET /capture', () => {
cy.session().then(abc =>{
cy.request({
method: 'GET',
url: '/capture/'+target
})
})
})
the goal is to capture parse of JSON array from target = (response.body)
You have two options:
leave the code as is, be aware that the
.then(response => {
const target = (response.body)
})
code isn't returning anything so the cy.session().then(abc =>{ ... code is getting the whole response (abc is the response of the first .then)
change the code into
.then(response => {
const target = (response.body)
return target // I added this return
})
and then your abc param will be equal to response.body and not to response
That's because if you don't return a subject from your chainable calls the default one will be passed to the next .then function.
Let me know if it satisfies your issue.
p.s. Welcome 👋

Resources