My script is running well but at the end I get an error message Error during script execution.
Cannot set property 'status' of undefined.
Does anybody have a clue what I am doing wrong here?
const fs = require("fs-promise");
const axios = require("axios");
const jsonxml = require("jsonxml");
const tmp = require("tmp");
module.exports = {
mpGetChecklist: async function (mpurl, bearer, systemGetChecklistMethod, systemGetChecklistId, systemGetChecklistDatasetName) {
var getChecklist = {
method: systemGetChecklistMethod,
url: mpurl + "/connector/system/getChecklist?id=" + systemGetChecklistId,
headers: {
Authorization: "Bearer " + bearer,
},
};
let tmpPath = tmp.fileSync({ postfix: ".xml" });
let result;
await axios(getChecklist)
.then(function (response) {
console.log(JSON.stringify(response.data));
let xmlOptions = { header: true, root: "JSON", indent: true };
let xmlString = jsonxml(response.data, xmlOptions);
try {
fs.writeFileSync(tmpPath.name, xmlString);
result = { status: "succes", xmlPath: tmpPath.name, datasetName: systemGetChecklistDatasetName };
} catch (error) {
result = { status: "error", msg: error };
}
})
.catch(function (error) {
console.log(error);
});
return result;
},
};
Related
I am getting the error data: { success: false, error: 'Not logged in: Invalid signature' } for /wallet/balances. Interestingly, the same code runs for /wallet/coins and /markets for FTX REST API. The code is in JS
PLEASE HELP!!
const url = "https://ftx.us/api/wallet/balances"
const path = "/api/wallet/balances"
const timestamp = Date.now()
const method = "GET"
const payload = `{timestamp}{method}{url}`
const hash = CryptoJS.HmacSHA256(payload, process.env.FTX_API_SECRET)
// var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, "Secret Passphrase");
// hmac.update(JSON.stringify(timestamp));
// hmac.update(method);
// hmac.update(path);
// var hash = hmac.finalize();
const hash2 = crypto.createHmac('sha256', process.env.FTX_API_SECRET).update(payload).digest("hex")
console.log("API KEY ", process.env.FTX_API_KEY)
axios({
method: "get",
headers: {
"FTXUS-SIGN": CryptoJS.enc.Hex.stringify(hash),
// "FTXUS-SIGN": hash2,
"FTXUS-KEY": process.env.FTX_API_KEY,
"FTXUS-TS": timestamp,
},
url: url
})
.then( (response) => {
if (response.data.success) {
callback(null, response.data.result)
} else {
// error handling here for the api
callback(result.data.error)
}
})
.catch ( (e) => {
console.log("exception in request ", e)
})
add these 2 lines in headers,
{
"FTXUS-SIGN": CryptoJS.enc.Hex.stringify(hash),
"FTXUS-KEY": process.env.FTX_API_KEY,
"FTXUS-TS": timestamp,
"Content-Type": "application/json",
"Accepts": "application/json",
}
It worked for me
Still am able to get the accessToken successfully but don't understand why I'm getting auth.getAccessToken is not a function
index.js
$.ajax({
type: "GET",
url: "/getSingRpt",
dataType: "json",
success: function (embedData) {
let reportLoadConfig = {
type: "report",
tokenType: models.TokenType.Embed,
accessToken: embedData.accessToken,
embedUrl: embedData.embedUrl[0].embedUrl
};
tokenExpiry = embedData.expiry;
let report = powerbi.embed(reportContainer, reportLoadConfig);
report.off("loaded");
report.on("loaded", function () {
console.log("Report load successful");
});
report.off("rendered");
report.on("rendered", function () {
console.log("Report render successful");
});
report.off("error");
report.on("error", function (event) {
let errorMsg = event.detail;
console.error(errorMsg);
return;
});
},
error: function (err) {
let errorContainer = $(".error-container");
$(".embed-container").hide();
errorContainer.show();
let errMsg = JSON.parse(err.responseText)['error'];
let errorLines = errMsg.split("\r\n");
let errHeader = document.createElement("p");
let strong = document.createElement("strong");
let node = document.createTextNode("Error Details:");
let errContainer = errorContainer.get(0);
strong.appendChild(node);
errHeader.appendChild(strong);
errContainer.appendChild(errHeader);
errorLines.forEach(element => {
let errorContent = document.createElement("p");
let node = document.createTextNode(element);
errorContent.appendChild(node);
errContainer.appendChild(errorContent);
});
}
});
Server.js
app.get('/getSingRpt', async (req, res) => {
try {
await embedToken.getEmbedParamsForSingleReport().then((result) => {
console.log(result);
res.status(200).send({ success: true, data: result });
})
} catch (e) {
console.error(e);
res.status(400).send({ success: false, message: 'problem in getting report' });
}
});
embedSConfigService.js
async function getEmbedParamsForSingleReport(workspaceId, reportId, additionalDatasetId) {
const reportInGroupApi = `https://api.powerbi.com/v1.0/myorg/groups/${workspaceId}/reports/${reportId}`;
const headers = await getRequestHeader();
const result = await fetch(reportInGroupApi, {
method: 'GET',
headers: headers,
})
console.log('result', result);
if (!result.ok) {
throw result;
}
const resultJson = await result.json();
const reportDetails = new PowerBiReportDetails(resultJson.id, resultJson.name, resultJson.embedUrl);
const reportEmbedConfig = new EmbedConfig();
reportEmbedConfig.reportsDetail = [reportDetails];
let datasetIds = [resultJson.datasetId];
if (additionalDatasetId) {
datasetIds.push(additionalDatasetId);
}
reportEmbedConfig.embedToken = await getEmbedTokenForSingleReportSingleWorkspace(reportId, datasetIds, workspaceId);
return reportEmbedConfig;
}
async function getRequestHeader() {
let tokenResponse;
let errorResponse;
try {
tokenResponse = await auth.getAccessToken();
} catch (err) {
if (err.hasOwnProperty('error_description') && err.hasOwnProperty('error')) {
errorResponse = err.error_description;
} else {
errorResponse = err.toString();
}
return {
'status': 401,
'error': errorResponse
};
}
const token = tokenResponse;
console.log('TOKEN==>', tokenResponse)
return {
'Content-Type': "application/json",
'Authorization': utils.getAuthHeader(token)
};
}
Auth.js
const adal = require('adal-node');
const config = require(__dirname + '/../config/config.json');
const getAccessToken = () => {
return new Promise((resolve, reject) => {
try {
const authMode = config.authenticationMode.toLowerCase();
const AuthenticationContext = adal.AuthenticationContext;
let authorityUrl = config.authorityUri;
if (authMode === 'masteruser') {
new AuthenticationContext(
authorityUrl,
).acquireTokenWithUsernamePassword(
config.scope,
config.pbiUsername,
config.pbiPassword,
config.clientId,
(err, token) => {
if (err) reject(err);
resolve(token);
},
);
} else if (authMode === 'serviceprincipal') {
authorityUrl = authorityUrl.replace('common', config.tenantId);
new AuthenticationContext(
authorityUrl,
).acquireTokenWithClientCredentials(
config.scope,
config.clientId,
config.clientSecret,
(err, token) => {
if (err) reject(err);
resolve(token);
},
);
} else {
reject(new Error('Unknown auth mode'));
}
} catch (err) {
console.error(err);
reject(err);
}
});
};
getAccessToken()
.then((token) => console.log(token))
.catch((err) => console.error(err));
updated
utilities.js
let config = require(__dirname + "/../config/config.json");
function getAuthHeader(accessToken) {
// Function to append Bearer against the Access Token
return "Bearer ".concat(accessToken);
}
In the code block below, var ret=that.sendSMTPEmailForOrderPlaced(orderData); is not getting executed. The console is printing "before calling," but it is not printing "inside sendSMTPEmailForOrderPlaced" message. Getting error TypeError: Cannot read property 'sendSMTPEmailForOrderPlaced' of null in createNewOrderHistory method.createNewOrderHistory is called from Redux Saga
const result = yield call(MyProfileRepository.createNewOrderHistory, data);
What is wrong with the code below?
class MyRepository {
constructor(callback) {
this.callback = callback;
}
createNewOrderHistory(tableData) {
var that = this;
const AuthStr = 'Bearer ' + getToken();
let promises = [];
tableData.map((tableData, index) => {
var data = {
invoice_id: tableData.invoiceID.toString(),
};
promises.push(axios.post(`url`, data, {
headers: { Authorization: AuthStr },
}));
});
return Promise.all(promises).then(function(results) {
console.log("before calling")
var ret = that.sendSMTPEmailForOrderPlaced(orderData);
console.log("after calling")
console.log(ret);
return (results);
}).catch(error => {
return (error);
});
}
sendSMTPEmailForOrderPlaced(data) {
console.log("inside sendSMTPEmailForOrderPlaced")
const response = axios.post(`url`, data).then((response) => {
return response.data;
}).catch((error) => {
console.log(error);
return (error);
});
return response.data;
return null;
}
}
export default new MyRepository();
It's hard to test your code, but I believe that #Keith had the right idea in his comment. So to test it I had to change 'url' and so on. But this code should give you a good idea on how to write it:
const axios = require('Axios');
class MyRepository {
async createNewOrderHistory(tableData) {
var that = this;
const AuthStr = 'Bearer '; // + getToken();
const header = { headers: { Authorization: AuthStr } };
let promises = tableData.map((tableData, index) => {
var data = { invoice_id: tableData.invoiceID.toString() };
return axios.post('https://jsonplaceholder.typicode.com/posts', data, header);
});
const results = await Promise.all(promises).then(async (results) => {
console.log("before calling")
var ret = await that.sendSMTPEmailForOrderPlaced(results.data);
console.log("after calling", ret);
return (results);
}).catch(error => {
return (error);
});
console.log(results.map(a => a.data));
}
async sendSMTPEmailForOrderPlaced(data) {
console.log("inside sendSMTPEmailForOrderPlaced")
try {
const response = await axios.post('https://jsonplaceholder.typicode.com/posts', data);
return response.data;
} catch (error) {
return error;
}
}
}
var repo = new MyRepository();
repo.createNewOrderHistory([{ invoiceID: 'test' }, { invoiceID: 'test2' }, { invoiceID: 'test3' }]);
If you want to run this, past it into a test.js file in an empty folder, then run the following in the same folder:
npm init -y
npm i axios
node .\test.js
when user wants to to POST somthing he must be singed in(without username & pass).
Problem is i'm trying to make when CreatePost() invoked it will call SingUser() and based on SingUser() fetch request it will call CreatePost() again to let user post after he sign in.
this is in createpost component
CreatePost(){
fetch(url ,{
method :'POST',
headers:{
Accept:'application/json',
'Content-Type' :'application/json',
},
body: JSON.stringify(post)
}).then((response) => response.json())
.then((responseJson)=>{
if(responseJson.status =='inactive'){
//SignUser
}else{
//post
}
}).catch((error)=>{ //later
});
}
here is SingUser() in other file
async function SignUser() {
try{
User.vtoken = await AsyncStorage.getItem('vtoken');
var userTemp={
vtoken: User.vtoken,
ntoken : User.ntoken
}
fetch(url,{
method :'POST',
headers:{
Accep : 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(userTemp)
}).then((response)=> response.json()).
then((responseJson)=>{
if(responseJson.path == 2){
Save(responseJson, userTemp);}
else return;
}).catch((error)=>{
});
}catch(error){}
}
async function Save(result , userTemp){
try{
await AsyncStorage.setItem('vtoken', result.vtoken);
User.vtoken = result.vtoken;
userTemp.vtoken = result.vtoken;
fetch(url,{
method :'POST',
headers:{
Accep : 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(userTemp)
}).then((response)=>response.json()).
then((responseJson)=>{
return 'done';
}).catch((error)=>{})
}
catch(error){}
}
export {SignUser}
i hope u understand what im trying to do if there is better way to do it thnx:(
You can do something like this:
const errorCodeMap = {
USER_INACTIVE: 10,
}
const statusMap = {
INACTIVE: `inactive`
}
const METHOD = `POST`
const APPLICATION_JSON = `application/json`
const headerDefault = {
Accept: APPLICATION_JSON,
'Content-Type': APPLICATION_JSON,
}
const who = `post`
async function createPost(payload, options) {
try {
const {
url = ``,
fetchOptions = {
method: METHOD,
headers: headerDefault,
},
} = options
const {
post,
} = payload
const response = await fetch(url, {
...fetchOptions,
body: JSON.stringify(post)
})
const {
status,
someUsefulData,
} = await response.json()
if (status === statusMap.INACTIVE) {
return {
data: null,
errors: [{
type: who,
code: errorCodeMap.USER_INACTIVE,
message: `User inactive`
}]
}
} else {
const data = someNormalizeFunction(someUsefulData)
return {
data,
errors: [],
}
}
} catch (err) {
}
}
async function createPostRepeatOnInactive(payload, options) {
try {
const {
repeat = 1,
} = options
let index = repeat
while (index--) {
const { data, errors } = createPost(payload, options)
if (errors.length) {
await signUser()
} else {
return {
data,
errors,
}
}
}
} catch (err) {
}
}
solve it, I did little adjustments
async CreatePost(){
try{
var response = await fetch(url ,{
method :'POST',
headers:{
Accept:'application/json',
'Content-Type' :'application/json',
},
body: JSON.stringify(post)});
var responseJson = await response.json();
if(responseJson.status =='inactive' && postRepeat == true){
postRepeat == false;
await SignUser();
this.CreatePost();
}
else{
//posted
}
}catch(err){}
}
I am trying to call a function inside a for loop and the problem is that the function is called after the loop was finished.
Taking the below as an example, it prints to the console:
here1
here1
here2
here2
Instead of
here1
here2
here1
here2
report.forEach(item => {
item.runs.forEach(run => {
waComplianceBusiness(req, run.id, (err, res) => {
const compliance = res.data.overviews[0].compliance;
var failureList = [];
compliance.forEach((rule, index) => {
console.log('here1');
waRuleOverview(req, run.id, rule.id, (err, res) => {
console.log('here2');
// handle the response
});
});
});
});
});
How can I fix this?
Please let me know if I need to provide additional information
Here is the complete code:
export default (req, callback) => {
const report = req.body.webAudits;
if(report.length > 0) {
report.forEach(item => {
item.runs.forEach(run => {
waComplianceBusiness(req, run.id, (err, res) => {
const compliance = res.data.overviews[0].compliance;
if(compliance) {
var failureList = [];
compliance.forEach((rule, index) => {
if(rule.pagesFailed > 0) {
waRuleOverview(req, run.id, rule.id, (err, res) => {
const failedConditions = res.data.failedConditions;
const ruleName = res.data.ruleName;
failedConditions.forEach((condition, failedIndex) => {
const request = {
itemId: condition.conditionResult.id,
itemType: condition.conditionResult.idType,
parentId: condition.conditionResult.parentId,
parentType: condition.conditionResult.parentType
}
const body = {
runId: run.id,
ruleId: rule.id,
payload: request
}
waConditionOverview(req, body, (err, res) => {
const description = res.data.description;
const conditionValues = res.data.conditionValues[0];
var actualValue = conditionValues.value;
if(actualValue == "") {
actualValue = 'empty';
}
if(description.idType == "variable") {
var failureObj = {
ruleName: ruleName,
expected: description.name + ' ' + description.matcher + ' ' + description.expected[0],
actual: description.name + ' ' + description.matcher + ' ' + actualValue
};
}
else if(description.idType == "tag") {
var failureObj = {
ruleName: ruleName,
expected: description.name + '\n' + description.matcher,
actual: actualValue
};
}
failureList.push(failureObj);
});
});
});
}
if(key + 1 == compliance.length) {
console.log(failureList);
}
});
}
});
});
});
}
}
These are the callback functions:
export function waComplianceBusiness(req, runId, callback) {
const apiToken = req.currentUser.apiToken;
const payload = {
'Authorization': 'api_key ' + apiToken
}
const options = {
'method': 'get',
'gzip': true,
'headers': payload,
'content-type': 'application/json',
'json': true,
'url': 'api_url'
}
request(options, (error, response, body) => {
callback(null, body);
});
}
export function waRuleOverview(req, runId, ruleId, callback) {
const apiToken = req.currentUser.apiToken;
const payload = {
'Authorization': 'api_key ' + apiToken
}
const options = {
'method': 'get',
'gzip': true,
'headers': payload,
'content-type': 'application/json',
'json': true,
'url': 'api_url'
}
request(options, (error, response, body) => {
callback(null, body);
});
}
export function waConditionOverview(req, body, callback) {
const apiToken = req.currentUser.apiToken;
const payload = {
'Authorization': 'api_key ' + apiToken
}
const options = {
'method': 'post',
'gzip': true,
'headers': payload,
'body': body.payload,
'content-type': 'application/json',
'json': true,
'url': 'api_url'
}
request(options, (error, response, body) => {
callback(null, body);
});
}
My goal is to return the failureList array after the loop over the compliance array is done
I found a similar question here but not sure if that would work in my case and I don't really know how to implement the promises
The for loop executes the statements inside the scope sequentially. But it does not wait for the the function calls to complete, it continues with the next statement(i.e works asynchronously). That is why the result is as such. You can make it work synchronously using Promises or by using the async module.
As it is not clear what you are going to perform in the function call and what you want the statements to do, I am not able to suggest either of which. . asyn.each is usually preferred for making the for loop execute synchronously. And promises are used when you want to wait for the function to finish executing and then perform operation. You might want to look at their documentation
Promises|MDN
async.each
Thank you, Ragul
If you want to do it in sequence use async.eachOfSeries
async.eachOfSeries(report, function(item, index, eachOfCallback1){
async.eachOfSeries(item.runs, function(run, index, eachOfCallback2){
waComplianceBusiness(req, run.id, (err, res) => {
var failureList = [];
async.eachOfSeries(compliance, function(rule, index, eachOfCallback3){
console.log('here1');
waRuleOverview(req, run.id, rule.id, (err, res) => {
console.log('here2');
return eachOfCallback3(err);
});
}, function(err){
if(err)
return eachOfCallback2(err);
else return eachOfCallback2();
});
});
}, function(err){
if(err)
return eachOfCallback1(err);
else return eachOfCallback1();
})
}, function(err){
// handle final response
})
If you want to optimise the process take a look at async.parallel