Axios get URL not working after concatenation - javascript

I am having a problem using Axios with node js. Here is my code
let callResult = await axios.get(urlData, config)
Where config is
let config = {
headers: {
'X-Token': token
}
};
And the urlData is
let urlData = 'https://api.regulaforensics.com/webapi/Transaction2/GetTransactionResultJson?transactionId=<IDVariable>&resultType=15'
I am trying to add my IDVariable to the URL but it does not work. If I take the variable and put it directly in the URL I get a response.
I have also tried this
let config = {
headers: {
'X-Token': token
},
params: {
transactionId: IDVariable,
resultType: 15
}};
And this
let querys = querystring.stringify({ transactionId: keyId, resultType: 15 })
let path = 'https://api.regulaforensics.com/webapi/Transaction2/GetTransactionResultJson?'
let urlData = path.concat("", querys)
This is the complete URL
https://api.regulaforensics.com/webapi/Transaction2/GetTransactionResultJson?transactionId=05cc6ccc-3ae6-4185-b2c9-1e1aba01d705&resultType=15
When using {params: } or concatenation
When putting the whole URL. As the URL I pasted above
This is my whole function

If you want to pass some parameters as a query string you can use the following syntax for the GET request:
axios.get('/user', { params: { ID: 12345 } });
Tath will be translated in the following request:
/user?ID=12345
As explained in the documentation here: https://github.com/axios/axios#note-commonjs-usage
Note
You don't need to add the ? char at the end of URL and you don't need to have the parameters in the URL, so the part ?transactionId=<IDVariable>&resultType=15 must be removed

I found the solution.
I am calling a service first and the response of that service is the key I need for the second service.
The solution was to just put a sleep() between those two services.
Thanks you for your response, guys!

Related

Cypress cy.api request fails when URL is returned by enum

When trying to make a request to API endpoint using Cypress, different results are returned when url is directly passed or from a method/enum. Not sure how to go about it as I don't want to hardcode the urls in request.
const SPACEID = some_space_id
const ENVIRONMENTID = development
const ENTRIES_EP = entries
const CONTENT_TYPE_EP = contentType
enum endPoints {
entries = `https://app.contentful.com/spaces/${SPACEID}/environments/${ENVIRONMENTID}/${ENTRIES_EP}`,
content_type = `https://app.contentful.com/spaces/${SPACEID}/environments/${ENVIRONMENTID}/${CONTENT_TYPE_EP}`,
}
cy.api({
method: 'GET',
url: String(endPoints.content_type),
auth: {
bearer: `SOME_TOKEN`,
},
}).then((response) => {
expect(response.status).to.eq(200)
cy.wrap(response).as('resp')
})
The code above returns some HTML content stating only Chrome, Firefox is supported.
However if I add the absolute URL in cy.api call it works fine. I am not sure what I am doing wrong as I have compared both URLs and they are exactly same.
https://app.contentful.com/spaces/some_space_id/environments/development/content_types
https://api.contentful.com/spaces/some_space_id/environments/development/content_types

Read settings contained in a json file in javascript

Im tring to read a simple setting from a json file, the json is this :
{
"Label": "some string here"
}
form my javascript part i do:
import settings from '../settings.json';
then:
var settings= ()=> {
const headers = new Headers();
const requestOptions = {
method: 'GET',
headers: { ...headers.authentication, ...headers.culture, 'ContentType':'application/json',
};
return fetch(`${settings.Label}`, requestOptions).then(() => {
return response.text().then(text => {
const data = text ? text && JSON.parse(text) : {};
let token = response.headers.get('X-Token');
if (token) {
data.token = token;
}
if (!response.ok) {
// manage error here
}
return Promise.reject(error);
}
return data;
})
});
};
// use settings here
Despite my many searches and attempts im not very expert in javascript,i have tried in many ways before, but the my variable 'settings' is not contain nothing.
I believe you need to add an export to your JSON file
export const settings = {
"label": "some string here"
}
Not much information given here, but this probably has to do with transpiling your javascript. You can use:
const settings = require('../settings.json')
instead.
try this answer https://stackoverflow.com/a/59844868/7701381
Also, change the name of the imported json settings or the var settings, cuz this might cause unexpected behaviors
I had completely wrong the approach, the file is already available and I don't have to request to download it from the server, I just have to return string, without use of fetch or other:
return (`${settings.Label}`
Sorry and thank a lot for the support

How to Login to MediaWiki (Wikipedia) API in Node.js

I'm trying the Wikipedia client login flow depicted in the API:Login docs, but something wrong happens:
1) I correctly get a token raised with the HTTP GET https://en.wikipedia.org/w/api.php?action=query&meta=tokens&type=login&format=json
and I get a valid logintoken string.
2.1) I then try the clientlogin like:
HTTP POST /w/api.php?action=clientlogin&format=json&lgname=xxxx&lgtoken=xxxx%2B%5C
and the POST BODY was
{
"lgpassword" : "xxxxx",
"lgtoken" : "xxxxx"
}
But I get an error:
{
"error": {
"code": "notoken",
"info": "The \"token\" parameter must be set."
},
"servedby": "mw1228"
}
If I try to change lgtoken to token I get the same result.
2.2) I have then tried the old method i.e. action=login and passing the body, but it does not work, since it gives me back another login token: HTTP POST https://en.wikipedia.org/w/api.php?action=login&format=json&lgname=xxxx
and the same POST BODY
I then get
{
"warnings": {}
},
"login": {
"result": "NeedToken",
"token": "xxxxx+\\"
}
where the docs here states that
NeedToken if the lgtoken parameter was not provided or no session was active (e.g. your cookie handling is broken).
but I have passed the lgtoken in the json body as showed.
I'm using Node.js and the built-in http module, that is supposed to pass and keep session Cookies in the right way (with other api it works ok).
I have found a similar issue on a the LrMediaWiki client here.
[UPDATE]
This is my current implementation:
Wikipedia.prototype.loginUser = function (username, password) {
var self = this;
return new Promise((resolve, reject) => {
var cookies = self.cookies({});
var headers = {
'Cookie': cookies.join(';'),
'Accept': '*/*',
'User-Agent': self.browser.userAgent()
};
// fetch login token
self.api.RequestGetP('/w/api.php', headers, {
action: 'query',
meta: 'tokens',
type: 'login',
format: 'json'
})
.then(response => { // success
if (response.query && response.query.tokens && response.query.tokens['logintoken']) {
self.login.logintoken = response.query.tokens['logintoken'];
self.logger.info("Wikipedia.login token:%s", self.login);
return self.api.RequestPostP('/w/api.php', headers, {
action: 'login',
format: 'json',
lgname: username
},
{
lgpassword: password,
lgtoken: self.login.logintoken
});
} else {
var error = new Error('no logintoken');
return reject(error);
}
})
.then(response => { // success
return resolve(response);
})
.catch(error => { // error
self.logger.error("Wikipedia.login error%s\n%#", error.message, error.stack);
return reject(error);
});
});
}//loginUser
where this.api is a simple wrapper of the Node.js http, the source code is available here and the api signatures are like:
Promise:API.RequestGetP(url,headers,querystring)
Promise:API.RequestPostP(url,headers,querystring,body)
If the currently accepted answer isn't working for someone, the following method will definitely work. I've used the axios library to send requests. Any library can be used but the key lies in formatting the body and headers correctly.
let url = "https://test.wikipedia.org/w/api.php";
let params = {
action: "query",
meta: "tokens",
type: "login",
format: "json"
};
axios.get(url, { params: params }).then(resp => {
let loginToken = resp.data.query.tokens.logintoken
let cookie = resp.headers["set-cookie"].join(';');
let body = {
action: 'login',
lgname: 'user_name',
lgpassword: 'password',
lgtoken: loginToken,
format: 'json'
}
let bodyData = new URLSearchParams(body).toString();
axios.post(url, bodyData, {
headers: {
Cookie: cookie,
}
}).then(resp => {
// You're now logged in!
// You'll have to add the following cookie in the headers again for any further requests that you might make
let cookie = resp.headers["set-cookie"].join(';')
console.log(resp.data)
})
})
And you should be seeing a response like
{
login: { result: 'Success', lguserid: 0000000, lgusername: 'Username' }
}
The second post request was where I got stuck for several hours, trying to figure out what was wrong. You need to send the data in an encoded form by using an API like URLSearchParams, or by just typing up the body as a string manually yourself.
I think from what you are saying you have lgtoken and lgname in the URL you are using, and then lgpassword and lgtoken (again!) in a JSON-encoded POST body.
This is not how the Mediawiki API works.
You submit it all as POST parameters. JSON is never involved, except when you ask for the result to come back in that format. I can't help you fix your code as you don't provide it, but that's what you need to do. (If you edit your question with your code, I'll do my best to help you.)
After seeing your code, I'll presume (without knowing the detail of your code) that you want something like this:
return self.api.RequestPostP('/w/api.php', headers, {
action: 'login',
format: 'json',
lgname: username,
lgpassword: password,
lgtoken: self.login.logintoken
});

How to get data from factory and send it in headers?

Hi I am developing web application in angularjs. I am making lot of http calls to interact with web api. As a result i have to send lot of data in headers too. I have created factory for get data as below. These data should should be passed in headers. Below is my factory.
var myapp = angular.module('RoslpApp');
myapp.factory("ScrollFunction", ['$location', '$anchorScroll', '$cookieStore', function ($location, $anchorScroll, $cookieStore) {
return {
getheaders: function () {
var cookiePreferredLanguage = $cookieStore.get('PreferredLanguage');
var headers={
Logintoken: $cookieStore.get('LoginToken'),
LoginId: $cookieStore.get('LoginID'),
RequestedPlatform: "Web",
RequestedLanguage: cookiePreferredLanguage
};
return headers;
}
}
}
]);
Below is my sample http call.
function getpermissiondetails() {
var headersdata = ScrollFunction.getheaders();
$scope.Create = "Create";
var getsavedvechilceUrl = baseurl + "api/RolesPermission/getgroups";
var request = {
url: getsavedvechilceUrl,
method: 'GET',
headers: {
RequestedPlatform: headersdata.RequestedPlatform,
RequestedLanguage: headersdata.RequestedLanguage,
Logintoken: headersdata.LoginToken,
LoginId: headersdata.LoginID
}
};
$http(request).then(function (response) {
$scope.groups = response.data.data;
}, function (error) {
})
}
What i want in header is i already have data in var headersdata = ScrollFunction.getheaders(); Is it possible to pass something like headers: { headersdata } because i can make add headers in factory. No need to expand it in each http call. I tried headers: { headersdata } but this is not sending any data to api. May i know is there any better solution? Any help would be appreciated. Thank you.
I guess this is a code refractoring question.
Q: Can I avoid doing the messy property assignment by doing something shortcut like headers={ factory data }?
A: Ok. I probably did a bad job paraphrasing your question. I'm just trying to make it more understandable.
Short answer: Yes. You can further shorten your code by doing this.
var request = {
url: getsavedvechilceUrl,
method: 'GET',
headers: ScrollFunction.getheaders()
};
Why?
Your function getheaders() is already returning a javascript object which is exactly what request.headers is looking. An object {}.
Since getHeaders() is already returning an object you can just plug it straight into request.headers. That is, you no need to re-create an object and reassign the property back in one by one.
Hope this helps.

Node.js - Can't post nested/escaped JSON to body using Fermata REST client

The problem may be with the actual client, but he's not responding on github, so I'll give this a shot!
I'm trying to post, in the body, nested JSON:
{
"rowkeys":[
{
"rowkey":"rk",
"columns":[
{
"columnname":"cn",
"columnvalue":"{\"date\":\"2011-06-21T00:53:10.309Z\",\"disk0\":{\"kbt\":31.55,\"tps\":6,\"mbs\":0.17},\"cpu\":{\"us\":5,\"sy\":4,\"id\":90},\"load_average\":{\"m1\":0.85,\"m5\":0.86,\"m15\":0.78}}",
"ttl":10000
},
{
"columnname":"cn",
"columnvalue":"cv",
"ttl":10000
}
]
},
{
"rowkey":"rk",
"columns":[
{
"columnname":"cn",
"columnvalue":"fd"
},
{
"columnname":"cn",
"columnvalue":"cv"
}
]
}
]
}
When I remove the columnvalue's json string, the POST works. Maybe there's something I'm missing regarding escaping? I've tried a few built in escape utilities to no avail.
var jsonString='the json string above here';
var sys = require('sys'),
rest = require('fermata'), // https://github.com/andyet/fermata
stack = require('long-stack-traces');
var token = ''; // Username
var accountId = ''; // Password
var api = rest.api({
url : 'http://url/v0.1/',
user : token,
password : accountId
});
var postParams = {
body: jsonString
};
(api(postParams)).post(function (error, result) {
if (error)
sys.puts(error);
sys.puts(result);
});
The API I'm posting to can't deserialize this.
{
"rowkeys":[
{
"rowkey":"rk",
"columns":[
{
"columnname":"cn",
"columnvalue":{
"date":"2011-06-21T00:53:10.309Z",
"disk0":{
"kbt":31.55,
"tps":6,
"mbs":0.17
},
"cpu":{
"us":5,
"sy":4,
"id":90
},
"load_average":{
"m1":0.85,
"m5":0.86,
"m15":0.78
}
},
"ttl":10000
},
{
"columnname":"cn",
"columnvalue":"cv",
"ttl":10000
}
]
},
{
"rowkey":"rk",
"columns":[
{
"columnname":"cn",
"columnvalue":"fd"
},
{
"columnname":"cn",
"columnvalue":"cv"
}
]
}
]
}
Dual problems occuring at the same occurred led me to find an issue with the fermata library handling large JSON posts. The JSON above is just fine!
I think the real problem here is that you are trying to post data via a URL parameter instead of via the request body.
You are using Fermata like this:
path = fermata.api({url:"http://example.com/path");
data = {key1:"value1", key2:"value2"};
path(data).post(callback);
What path(data) represents is still a URL, with data showing up in the query part. So your code is posting to "http://example.com/path/endpoint?key1=value1&key2=value2" with an empty body.
Since your data is large, I'm not surprised if your web server would look at such a long URL and send back a 400 instead. Assuming your API can also handle JSON data in the POST body, a better way to send a large amount of data would be to use Fermata like this instead:
path = fermata.api({url:"http://example.com/path");
data = {key1:"value1", key2:"value2"};
path.post(data, callback);
This will post your data as a JSON string to "http://example.com/path" and you would be a lot less likely to run into data size problems.
Hope this helps! The "magic" of Fermata is that unless you pass a callback function, you are getting local URL representations, instead of calling HTTP functions on them.

Categories