How to use axios to edit and update a page's html? - javascript

I'm using axios and an API to get a page's HTML, editing the HTML, and putting it back via a POST request to the API. I'm successful in retrieving and editing the HTML but I can't figure out how to put it back/change the webpage's HTML.
I tried using a PUT request instead of a POST request, but I get a 405 error that the PUT method is not allowed for the webpage.
axios.get(url, {
auth: {
username: USERNAME,
password: PASSWORD
},
headers: {
'Content-Type': 'application/json'
}
})
.then( (response) => {
version = response.data.version.number;
body = response.data.body.storage.value;
// takes the body HTML and formats all the links
newBody = middleware.formatLinks(body);
data = {
"type": "page",
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}
// put the body HTML back into the page
axios.post(url, {
data: {
"type": "page",
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}
}, {
auth: {
username: USERNAME,
password: PASSWORD
},
headers: {
'Content-Type': 'application/json'
}
})
.then( (response) => {
console.log(response.data);
})
.catch( (error) => {
console.log(error);
})
})
.catch( (error) => {
console.log(error);
})
I expect the page to now be updated with all the links formatted to my liking. However the page is unchanged. When I console.log(response.data) after making the post request, the output is a string of newBody, when I expect it to be the JSON object
data: {
'type': 'page',
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}

As mentioned in my comment in #Aman Raj's answer, I have the code working in python but translating it to nodejs was giving me issues. So I circumvented my problem by calling my python script in nodejs with the python-shell package.
let {PythonShell} = require('python-shell');
...
const formatLinks = (id) => {
let options = {
mode: 'text',
pythonOptions: ['-u'], // get print results in real-time
scriptPath: './python/', // path to my python scripts
// pass in the page id, username, and password to API request
args: [id, USERNAME, PASSWORD]
};
PythonShell.run('script.py', options, (err, results) => {
if (err) throw err;
// results is an array consisting of messages collected during execution
console.log('results: %j', results);
});
}

Your code seems fine. It may be possible that you are accessing an API which does not support editing it.
The HyperText Transfer Protocol (HTTP) 405 Method Not Allowed response
status code indicates that the request method is known by the server
but is not supported by the target resource.

Related

MailChimp Error Status: 401 Title: "API Key Invalid"

I am following a MailChimp API tutorial
When I test the API, I get a 401 response saying my API key is invalid.
Error -
Status: 401
"Your API key may be invalid, or you've attempted to access the wrong datacenter."
I have yet to register a domain yet, this is being testing using a local server. Could this be error be caused by MailChimp's refusing the request for another reason, perhaps CORS?
app.post('/signup', (req, res) => {
// Get form data
const { email } = req.body;
// Make sure field is filled
if(!email) {
res.redirect('/html/fail.html');
return;
}
// Construct req data
const data = {
members: [
{
email_address: email,
status: 'subscribed'
}
]
}
// Convert to JSON
const postData = JSON.stringify(data);
const options = {
url: 'https://us19.api.mailchimp.com/3.0/lists/listID',
method: 'POST',
headers: {
Authorization: 'auth xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us19'
},
body: postData
};
request(options, (err, response, body) => {
if(err) {
console.log(err);
res.redirect('/html/fail.html');
} else {
if(response.statusCode === 200) {
res.redirect('/html/success.html');
} else {
console.log(response.body);
res.redirect('/html/fail.html');
}
}
});
})
I tried running the same code in request in PostMan and I got back a 200 response.
I was initially importing the API key from a config file, that I had not destructured...

ReactJS and Node.JS [JSON.parse: unexpected character at line 1 column 1 of the JSON data]

I'm getting struggle with this code, so I need a third eye on this to find a solution.
I'm developing a ReactJS app with a REST API with Node.JS (Express), and I'm getting this error:
SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"
I'm using Sequelize ORM to work with Models and Database in Node.JS.
I'm also using CORS module for Node.JS.
This implementation works fine.
// Node.js Route for login
const router = require('express').Router();
const User = require('user');
router.post("/login", async (req, res) => {
try {
await User.findOne({
where: {
email: req.body.email,
password: req.body.password,
}
}).then((user) => {
if (!user) {
return res.send({message: "Login error!"});
} else {
const userData = {id: user.id, email: user.email};
res.send({"user": userData});
}
}).catch((err) => {
return res.send(err);
});
} catch (err) {
return res.send(err);
}
});
// ReactJS for login
loginFunction(e, data) {
e.preventDefault();
fetch('http://localhost:4500/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(json => {
this.setState({'user': json['user']});
})
.catch((err) => {
console.log(err);
this.setState({errors: "Login error"})
});
}
On the other hand, this implementation do not work properly and throws the SyntaxError above:
// Node.JS for Posts
const router = require('express').Router();
const Post = require('post');
router.get("/posts", async (req, res) => {
try {
await Post.findAndCountAll()
.then((posts) => {
res.send({"posts": posts});
}).catch((err) => {
return res.send(err);
});
} catch (err) {
return res.send(err);
}
});
// ReactJS for Posts
postsFunction() {
fetch('http://localhost:4500/posts', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(json => {
this.setState({'posts': json.posts.rows});
})
.catch((err) => {
console.log(err);
this.setState({errors: "Posts error."})
});
}
As you can see both implementation have little differences, What am I missing?
PS: When I test the 2nd implementation on Postman, data is retrieving successfully.
try removing headers when using GET method
headers: {
'Content-Type': 'application/json'
}
Try to use res.json instead of res.send in the node js function that cause the error.
I found the issue!
I follow the (#vengleab so) suggestion:
console log response instead of response => response.json()
I'm realize that response returns an object like this:
Response: {
body: ReadableStream
locked: false
<prototype>: object { … }
bodyUsed: false
headers: Headers { }
ok: true
redirected: false
status: 200
statusText: "OK"
type: "basic"
url: "http://localhost:3000/admin/undefined/posts"
}
The URL attribute contain an undefined value, so when I try to console.log the .env variable API_URL that contains the localhost URL used in this line:
fetch('http://localhost:4500/posts', {
That in real function is:
fetch(process.env.API_URL + '/posts', {
The result of the console.log was undefined.
As it is explained in Create React App docs, the environment variables must start with the prefix REACT_APP_.
Finally the line works as:
fetch(process.env.REACT_APP_API_URL + '/posts', {
I found that it was because my front end react url pointed to the same url as my backend server.js running mongodb. Also clearing the cookies on the browser seems to have helped as well.

Redmine Rest API : How do I upload a Wiki Page with an attach file

I wrote a script that take in a document and convert it into a string and send it to redmine as a wiki page. THIS WORKED GREAT.
NOW, I am trying to attach a file to it and the wiki page is being created and uploaded with the expected text, however, the attach file is not being sent.
And the weird thing is, I am not getting an error saying it is not being sent. I am actually getting a 201 response for the post request of the attach file, which is good but I am not seeing the file attach in the wiki page.
I also receive the token when i post the attachment so i can use it to do a PUT request with both the wiki text and the attach file, so you can see why I am so confuse.
I will provide my code in the file. Any help would be much appreciated.
//a path to a txt file in my computer
var filePath = '../attached.txt'
fs.readFile(filePath,"utf8", (err, data) => {
if (err) { throw err; }
creatingWikiPage_AttachedFile(data)
console.log(data)
})
function creatingWikiPage_AttachedFile(file) {
axios({
method: 'post',
url: '<redmine_url>/uploads.json',
headers: {
'Content-Type': 'application/octet-stream'
},
params: { 'key': '<api_key>' },
data: file
})
.then(function (response) {
console.log(" POST attached Files---> ");
console.log(response)
axios({
method: 'put',
url: '<redmine_url>/projects/Testing/wiki/Wiki.json',
headers: { 'Content-Type': 'application/json' },
params: { 'key': '<api_key>' },
data: {
"wiki_page": {
"text": "This is a wiki page with images and other files.",
"uploads": [
{ "token": response.data.upload.token, "filename": "attached.txt", "content-type": "text/plain" }
]
}
}
})
.then(response => {
console.log("Put Document-------->>>>")
console.log(response);
})
.catch(error => {
console.log(error.response)
})
})
.catch(function (error) {
console.log(error.message)
})
}
I am expecting the File to be attach to the wiki page, but only the wiki page is being created and the attach file is not there.

how to pass value in api body in protractor while requesting the api

I want to pass the value in API request body.
I tried below code for that
var options = { method: 'POST',
url: 'https://ssgpreprod.serviceurl.in/gonogo-api/atm/tw/cro-approval',
headers:
{ 'Postman-Token': '9d6a0ad1-c3a1-402f-b845-b6416f49df6b',
'cache-control': 'no-cache',
'Content-Type': 'application/json' },
body:
{ oHeader:
{ sReqType: 'application/json',
sAppSource: 'WEB 2.02.01',
sSourceID: 'GONOGO_HDBFS',
sAppID: 610961419000670,
dtSubmit: '',
sCroId: 'HDB_TW_CRO#cell.com',
sDsaId: 'default',
sInstID: 4019,
sUserName: 'CHDBTWCRO',
sProduct: 'TW',
sDealerId: '61096' },
sRefID:testData.twPreIpa.twReferenceId,
sAppStat: testData.twCroDetails.twCroDecision,
aCroJustification: [ { sRemark: testData.twCroDetails.twRemark, sSubTo: testData.twCroDetails.twSubjectTo} ],
bApprAmtExist: true,
dApprAmt: testData.twApplyDetails.twLoanAmount,
dItrRt: testData.twCroDetails.twRoi,
dLtv: testData.twCroDetails.twLtv,
aDedupeRefID: [] },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
browser.logger.info(JSON.stringify(body));
browser.logger.info(JSON.stringify(response));
browser.logger.info('status code is : ' + response.statusCode);
expect(response.statusCode).toBe(200).then(function () {
browser.logger.info('case is approved');
this.logOut(testData);
})
});
I am passing value from xlsx file i.e testData.twPreIpa.twReferenceId but I am getting 422 status code and below output
[2019-05-28 15:42:10.403] [INFO] : - {"title":"Conversion Failed","status":422,"detail":"The content you've sent is probably malformed."}
Also, when I add - browser.logger.info('approved'); above var options it prints on console.. but when I add - browser.logger.info(testData.twPreIpa.twReferenceId);
It gives me error .. ouput displayed -
Failed: Cannot read property 'twReferenceId' of undefined
TypeError: Cannot read property 'twReferenceId' of undefined
While this may not directly answer your question it should be helpful to you.
I worked on a similar framework to what (I assume) yours looks like,some api and some UI validations.
I had a separate class for my API calls which returned some value, sometimes the entire response body. I allowed myself the ability to pass in whatever body I needed as a parameter.
This is an example of the approach I took.
module.exports = class Endpoints {
addSomethingToUser(bearerToken, userId, JSONbody) {
//Function will preform a POST request and return the status code if successful
//Else if will return the body of the response
let endpoint = 'http://myApp.com:9090/api/users/' + userId;
return new Promise((resolve, reject) => {
let options = {
method: "POST",
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token,
},
body: JSON.stringify(JSONbody),
};
request(
endpoint,
options ,
function (error, response, body) {
if (!error && (response.statusCode >= 200 && response.statusCode < 300)) {
resolve(response.statusCode);
} else {
console.log('error:', error, response && response.statusCode);
reject(JSON.stringify(response, undefined, 2));
};
}
);
});
};
}
It is called like
let apiCallsFile = require('../apiCalls/restCalls');
let apiCalls = new apiCallsFile();
it('simple test', async function(){
let requiredBody = {
"NAME": "Test Name",
"GENDER": "MALE",
};
let apiResult = await apiCalls.addSomethingToUser(bearerToken, userId, requiredBody );
expect(apiResult).toBe('201');
}
Your issue seems to be related to the actual values you are using from excel. You should attempt to print out your values before attempting to send the request to ensure they are all present and in the format you expect.

Understanding HTTP requests --- authenticating with rapidgator--- how does it work?

I am confused about http requests and how it works when requesting links.
So I know a GET requests adds parameters to urls like ?username=ABC123&password=TTT and POST just sends data to the server but thats all I get when reading tutorials out there. How would I for example send a request and download a file from a rapidgator link after authenticating? (I am a premium user).
Link to their api doc:
https://support.rapidgator.net/index.php?/Knowledgebase/Article/View/89/9/do-you-have-api
The first response gives back a response object like this which gives the session id which is where I got the session id from:
{
"response": {
"expire_date":1351526400,
"traffic_left":0,
"reset_in":11695
},
"response_status":200,
"response_details":null
}
This is my code:
const rp = require('request-promise');
const url = 'http://rapidgator.net/api/user/login';
const opts = {
uri: url,
qs: {
username: '**censored**',
password: '**censored**',
},
headers: {
'User-Agent': 'Request-Promise'
},
json: true
}
rp(opts)
.then(( resp ) => {
const sessionId = resp.session_id;
const postOpts = {
uri: 'http://rapidgator.net/api/user/info?sid=knf3pqpg3ldm05qnol0sn16326',
method: 'POST',
body: {
session_id: sessionId
},
json: true
}
rp(postOpts)
.then(res => {
console.log(cyan(JSON.stringify(res, null, 2)));
})
})
.catch(( err ) => {
throw Error(err);
});
Am I approaching this the wrong way? How do I proceed to download links from rapidgator?

Categories