JavaScript Promise return value from function - javascript

Relatively new to JavaScript Promises.
Trying to call a function - checktheData(recordidGuid) from within a Promise
and use the result in a .then chain.
The last line of the checktheData function is:
return outcomeString
My problem is that the result of the promise is "undefined", yet when I output it to the console in the checktheData function it is as expected
I know I need to add a return statement, but where please?
Simple code:
function masterDeploy(PrimaryControl){
var formContext = PrimaryControl;
formContext.data.refresh(true);
var recordidGuid = ""
recordidGuid = formContext.data.entity.getId();
var loggedinuser =
Xrm.Utility.getGlobalContext().userSettings.userId;
recordidGuid = recordidGuid.replace('{', '').replace('}', '');
loggedinuser = loggedinuser.replace('{', '').replace('}', '');
var outcomeString = ""
var checkOutcome = false;
let promise = new Promise(function(resolve, reject) {
resolve(checktheData(recordidGuid))
});
promise.then(
result => {
console.log(promise);
}
),
promise.catch(
function (error){
DisplayError(error)}
);
return // stops here whilst debugging
if (checkOutcome == true){
var alertStrings = { confirmButtonLabel: "Close", text: outcomeString, title: "Data check failed" };
var alertOptions = { height: 500, width: 1000 };
Xrm.Navigation.openAlertDialog(alertStrings, alertOptions).then(
function success(result) {
return;
},
function (error) {
DisplayError(error)
});
}
else{
if(checkOutcome == false){
//2. Create the learner journal url
buildLearnerEntryURL(recordidGuid,loggedinuser)
if(checkOutcome == false){
//3. Create refinery user and enrol on courses
createUserandEnrol(recordidGuid,loggedinuser)
if(checkOutcome == false){
//4. Create Learning Aims
createLearningAims(recordidGuid)
}
};
};
}
formContext.data.refresh(true);
//Set text to be a concatenated summary of actions completed or skipped
alertStrings = { confirmButtonLabel: "Close", text: "Deployment completed etc etc", title: "Deployment Completed" };
Xrm.Navigation.openAlertDialog(alertStrings, alertOptions).then(
function success(result) {
return;
},
function (error) {
DisplayError(error)
});
};
function checktheData(recordidGuid){
var outcomeString = ""
var checkOutcome = "false";
var str = "";
Xrm.WebApi.online.retrieveRecord("new_apprenticeshipflight", recordidGuid, "?$select=new_flighttype,new_programmelearningaimreference,new_apprenticeshipoverallaimreference,_new_mentor_value,_new_enrolledstandard_value,_new_clonelinkid_value,new_plannedstartdate,new_plannedenddate,crd80_overideendcalc,_new_contact_value,_new_apprenticeshipprogramme_value,_new_employer_value,_crd80_locationcontact_value,crd80_headofficedelivery,crd80_learningjournalurl,crd80_refineryid,crd80_addresstouse,_crd80_placementemployer_value,crd80_employeraddresstext,&$expand=new_Contact($select=emailaddress1,firstname,lastname),new_EnrolledStandard($select=crd80_learningjournalform),crd80_PlacementEmployer($select=name, accountid, address1_postalcode,address2_postalcode),crd80_LocationContact($select=emailaddress1,fullname,telephone1),new_Employer($select=name,address1_postalcode,address2_postalcode),new_Mentor($select=new_homepostcode),new_ApprenticeshipProgramme($select=crd80_learnerteamsiteurl)").then(
function success(result) {
if (result["new_flighttype"] == 100000001 && result["new_flighttype"] == null){outcomeString = outcomeString + "This must be a learner type flight"; checkOutcome = true};
//other lines removed for clarity
console.log(outcomeString)
return outcomeString
})
}

Xrm.WebApi.online.retrieveRecord return a promise, so you can just return it from checktheData().
What you need to handle is basically just to call the checktheData() and use .then() and .catch() for the result.
Example:
function masterDeploy(PrimaryControl) {
var formContext = PrimaryControl;
formContext.data.refresh(true);
var recordidGuid = "";
recordidGuid = formContext.data.entity.getId();
var loggedinuser = Xrm.Utility.getGlobalContext().userSettings.userId;
recordidGuid = recordidGuid.replace("{", "").replace("}", "");
loggedinuser = loggedinuser.replace("{", "").replace("}", "");
var outcomeString = "";
checktheData()
.then(checkOutcome => {
if (checkOutcome == true) {
var alertStrings = {
confirmButtonLabel: "Close",
text: outcomeString,
title: "Data check failed",
};
var alertOptions = { height: 500, width: 1000 };
Xrm.Navigation.openAlertDialog(alertStrings, alertOptions).then(
function success(result) {
return;
},
function (error) {
DisplayError(error);
}
);
} else {
if (checkOutcome == false) {
//2. Create the learner journal url
buildLearnerEntryURL(recordidGuid, loggedinuser);
if (checkOutcome == false) {
//3. Create refinery user and enrol on courses
createUserandEnrol(recordidGuid, loggedinuser);
if (checkOutcome == false) {
//4. Create Learning Aims
createLearningAims(recordidGuid);
}
}
}
}
formContext.data.refresh(true);
//Set text to be a concatenated summary of actions completed or skipped
alertStrings = {
confirmButtonLabel: "Close",
text: "Deployment completed etc etc",
title: "Deployment Completed",
};
Xrm.Navigation.openAlertDialog(alertStrings, alertOptions)
.then(function success(result) {
return;
})
.catch(error => {
DisplayError(error);
});
})
.catch(err => {
console.log(err);
});
}
function checktheData(recordidGuid) {
var outcomeString = "";
var checkOutcome = "false";
var str = "";
Xrm.WebApi.online
.retrieveRecord(
"new_apprenticeshipflight",
recordidGuid,
"?$select=new_flighttype,new_programmelearningaimreference,new_apprenticeshipoverallaimreference,_new_mentor_value,_new_enrolledstandard_value,_new_clonelinkid_value,new_plannedstartdate,new_plannedenddate,crd80_overideendcalc,_new_contact_value,_new_apprenticeshipprogramme_value,_new_employer_value,_crd80_locationcontact_value,crd80_headofficedelivery,crd80_learningjournalurl,crd80_refineryid,crd80_addresstouse,_crd80_placementemployer_value,crd80_employeraddresstext,&$expand=new_Contact($select=emailaddress1,firstname,lastname),new_EnrolledStandard($select=crd80_learningjournalform),crd80_PlacementEmployer($select=name, accountid, address1_postalcode,address2_postalcode),crd80_LocationContact($select=emailaddress1,fullname,telephone1),new_Employer($select=name,address1_postalcode,address2_postalcode),new_Mentor($select=new_homepostcode),new_ApprenticeshipProgramme($select=crd80_learnerteamsiteurl)"
)
.then(function success(result) {
if (
result["new_flighttype"] == 100000001 &&
result["new_flighttype"] == null
) {
outcomeString = outcomeString + "This must be a learner type flight";
checkOutcome = true;
}
//other lines removed for clarity
console.log(outcomeString);
return outcomeString;
});
}
Another example with async/await approach.
async function masterDeploy(PrimaryControl) {
var formContext = PrimaryControl;
formContext.data.refresh(true);
var recordidGuid = "";
recordidGuid = formContext.data.entity.getId();
var loggedinuser = Xrm.Utility.getGlobalContext().userSettings.userId;
recordidGuid = recordidGuid.replace("{", "").replace("}", "");
loggedinuser = loggedinuser.replace("{", "").replace("}", "");
var outcomeString = "";
const checkOutcome = await checktheData();
if (checkOutcome == true) {
var alertStrings = {
confirmButtonLabel: "Close",
text: outcomeString,
title: "Data check failed",
};
var alertOptions = { height: 500, width: 1000 };
try {
const result = await Xrm.Navigation.openAlertDialog(
alertStrings,
alertOptions
);
} catch (err) {
DisplayError(err);
}
} else {
if (checkOutcome == false) {
//2. Create the learner journal url
buildLearnerEntryURL(recordidGuid, loggedinuser);
if (checkOutcome == false) {
//3. Create refinery user and enrol on courses
createUserandEnrol(recordidGuid, loggedinuser);
if (checkOutcome == false) {
//4. Create Learning Aims
createLearningAims(recordidGuid);
}
}
}
}
formContext.data.refresh(true);
//Set text to be a concatenated summary of actions completed or skipped
alertStrings = {
confirmButtonLabel: "Close",
text: "Deployment completed etc etc",
title: "Deployment Completed",
};
try {
const result = await Xrm.Navigation.openAlertDialog(
alertStrings,
alertOptions
);
} catch (err) {
DisplayError(err);
}
}
async function checktheData(recordidGuid) {
var outcomeString = "";
var checkOutcome = "false";
var str = "";
const result = await Xrm.WebApi.online.retrieveRecord(
"new_apprenticeshipflight",
recordidGuid,
"?$select=new_flighttype,new_programmelearningaimreference,new_apprenticeshipoverallaimreference,_new_mentor_value,_new_enrolledstandard_value,_new_clonelinkid_value,new_plannedstartdate,new_plannedenddate,crd80_overideendcalc,_new_contact_value,_new_apprenticeshipprogramme_value,_new_employer_value,_crd80_locationcontact_value,crd80_headofficedelivery,crd80_learningjournalurl,crd80_refineryid,crd80_addresstouse,_crd80_placementemployer_value,crd80_employeraddresstext,&$expand=new_Contact($select=emailaddress1,firstname,lastname),new_EnrolledStandard($select=crd80_learningjournalform),crd80_PlacementEmployer($select=name, accountid, address1_postalcode,address2_postalcode),crd80_LocationContact($select=emailaddress1,fullname,telephone1),new_Employer($select=name,address1_postalcode,address2_postalcode),new_Mentor($select=new_homepostcode),new_ApprenticeshipProgramme($select=crd80_learnerteamsiteurl)"
);
if (
result["new_flighttype"] == 100000001 &&
result["new_flighttype"] == null
) {
outcomeString = outcomeString + "This must be a learner type flight";
checkOutcome = true;
}
//other lines removed for clarity
console.log(outcomeString);
return outcomeString;
}

Related

Append HTML tags using Cloudflare Workers

I'm using a Cloudflare Worker to load data from Backblaze B2. It generates a basic HTML page like this:
<html>
<head><meta name="viewport" content="width=device-width"></head>
<body>
<video>
<source src="myvideo.mp4" type="video/mp4">
</video>
</body>
</html>
I'm trying to modify the script so the browser will load a AV1-encoded version, if supported. If it is not then fallback to the WebM/VP9 version.
The HTML would look like the code below, but I cannot figure out how to modify the script correctly:
<html>
<head><meta name="viewport" content="width=device-width"></head>
<body>
<video>
<source src="myvideo.mp4" type="video/mp4">
<source src="myvideo.webm" type="video/webm">
</video>
</body>
</html>
The Worker code I'm using is:
"use strict";
(() => {
// node_modules/aws4fetch/dist/aws4fetch.esm.mjs
var encoder = new TextEncoder();
var HOST_SERVICES = {
appstream2: "appstream",
cloudhsmv2: "cloudhsm",
email: "ses",
marketplace: "aws-marketplace",
mobile: "AWSMobileHubService",
pinpoint: "mobiletargeting",
queue: "sqs",
"git-codecommit": "codecommit",
"mturk-requester-sandbox": "mturk-requester",
"personalize-runtime": "personalize"
};
var UNSIGNABLE_HEADERS = /* #__PURE__ */ new Set([
"authorization",
"content-type",
"content-length",
"user-agent",
"presigned-expires",
"expect",
"x-amzn-trace-id",
"range",
"connection"
]);
var AwsClient = class {
constructor({ accessKeyId, secretAccessKey, sessionToken, service, region, cache, retries, initRetryMs }) {
if (accessKeyId == null)
throw new TypeError("accessKeyId is a required option");
if (secretAccessKey == null)
throw new TypeError("secretAccessKey is a required option");
this.accessKeyId = accessKeyId;
this.secretAccessKey = secretAccessKey;
this.sessionToken = sessionToken;
this.service = service;
this.region = region;
this.cache = cache || /* #__PURE__ */ new Map();
this.retries = retries != null ? retries : 10;
this.initRetryMs = initRetryMs || 50;
}
async sign(input, init) {
if (input instanceof Request) {
const { method, url, headers, body } = input;
init = Object.assign({ method, url, headers }, init);
if (init.body == null && headers.has("Content-Type")) {
init.body = body != null && headers.has("X-Amz-Content-Sha256") ? body : await input.clone().arrayBuffer();
}
input = url;
}
const signer = new AwsV4Signer(Object.assign({ url: input }, init, this, init && init.aws));
const signed = Object.assign({}, init, await signer.sign());
delete signed.aws;
try {
return new Request(signed.url.toString(), signed);
} catch (e) {
if (e instanceof TypeError) {
return new Request(signed.url.toString(), Object.assign({ duplex: "half" }, signed));
}
throw e;
}
}
async fetch(input, init) {
for (let i = 0; i <= this.retries; i++) {
const fetched = fetch(await this.sign(input, init));
if (i === this.retries) {
return fetched;
}
const res = await fetched;
if (res.status < 500 && res.status !== 429) {
return res;
}
await new Promise((resolve) => setTimeout(resolve, Math.random() * this.initRetryMs * Math.pow(2, i)));
}
throw new Error("An unknown error occurred, ensure retries is not negative");
}
};
var AwsV4Signer = class {
constructor({ method, url, headers, body, accessKeyId, secretAccessKey, sessionToken, service, region, cache, datetime, signQuery, appendSessionToken, allHeaders, singleEncode }) {
if (url == null)
throw new TypeError("url is a required option");
if (accessKeyId == null)
throw new TypeError("accessKeyId is a required option");
if (secretAccessKey == null)
throw new TypeError("secretAccessKey is a required option");
this.method = method || (body ? "POST" : "GET");
this.url = new URL(url);
this.headers = new Headers(headers || {});
this.body = body;
this.accessKeyId = accessKeyId;
this.secretAccessKey = secretAccessKey;
this.sessionToken = sessionToken;
let guessedService, guessedRegion;
if (!service || !region) {
[guessedService, guessedRegion] = guessServiceRegion(this.url, this.headers);
}
this.service = service || guessedService || "";
this.region = region || guessedRegion || "us-east-1";
this.cache = cache || /* #__PURE__ */ new Map();
this.datetime = datetime || new Date().toISOString().replace(/[:-]|\.\d{3}/g, "");
this.signQuery = signQuery;
this.appendSessionToken = appendSessionToken || this.service === "iotdevicegateway";
this.headers.delete("Host");
if (this.service === "s3" && !this.signQuery && !this.headers.has("X-Amz-Content-Sha256")) {
this.headers.set("X-Amz-Content-Sha256", "UNSIGNED-PAYLOAD");
}
const params = this.signQuery ? this.url.searchParams : this.headers;
params.set("X-Amz-Date", this.datetime);
if (this.sessionToken && !this.appendSessionToken) {
params.set("X-Amz-Security-Token", this.sessionToken);
}
this.signableHeaders = ["host", ...this.headers.keys()].filter((header) => allHeaders || !UNSIGNABLE_HEADERS.has(header)).sort();
this.signedHeaders = this.signableHeaders.join(";");
this.canonicalHeaders = this.signableHeaders.map((header) => header + ":" + (header === "host" ? this.url.host : (this.headers.get(header) || "").replace(/\s+/g, " "))).join("\n");
this.credentialString = [this.datetime.slice(0, 8), this.region, this.service, "aws4_request"].join("/");
if (this.signQuery) {
if (this.service === "s3" && !params.has("X-Amz-Expires")) {
params.set("X-Amz-Expires", "86400");
}
params.set("X-Amz-Algorithm", "AWS4-HMAC-SHA256");
params.set("X-Amz-Credential", this.accessKeyId + "/" + this.credentialString);
params.set("X-Amz-SignedHeaders", this.signedHeaders);
}
if (this.service === "s3") {
try {
this.encodedPath = decodeURIComponent(this.url.pathname.replace(/\+/g, " "));
} catch (e) {
this.encodedPath = this.url.pathname;
}
} else {
this.encodedPath = this.url.pathname.replace(/\/+/g, "/");
}
if (!singleEncode) {
this.encodedPath = encodeURIComponent(this.encodedPath).replace(/%2F/g, "/");
}
this.encodedPath = encodeRfc3986(this.encodedPath);
const seenKeys = /* #__PURE__ */ new Set();
this.encodedSearch = [...this.url.searchParams].filter(([k]) => {
if (!k)
return false;
if (this.service === "s3") {
if (seenKeys.has(k))
return false;
seenKeys.add(k);
}
return true;
}).map((pair) => pair.map((p) => encodeRfc3986(encodeURIComponent(p)))).sort(([k1, v1], [k2, v2]) => k1 < k2 ? -1 : k1 > k2 ? 1 : v1 < v2 ? -1 : v1 > v2 ? 1 : 0).map((pair) => pair.join("=")).join("&");
}
async sign() {
if (this.signQuery) {
this.url.searchParams.set("X-Amz-Signature", await this.signature());
if (this.sessionToken && this.appendSessionToken) {
this.url.searchParams.set("X-Amz-Security-Token", this.sessionToken);
}
} else {
this.headers.set("Authorization", await this.authHeader());
}
return {
method: this.method,
url: this.url,
headers: this.headers,
body: this.body
};
}
async authHeader() {
return [
"AWS4-HMAC-SHA256 Credential=" + this.accessKeyId + "/" + this.credentialString,
"SignedHeaders=" + this.signedHeaders,
"Signature=" + await this.signature()
].join(", ");
}
async signature() {
const date = this.datetime.slice(0, 8);
const cacheKey = [this.secretAccessKey, date, this.region, this.service].join();
let kCredentials = this.cache.get(cacheKey);
if (!kCredentials) {
const kDate = await hmac("AWS4" + this.secretAccessKey, date);
const kRegion = await hmac(kDate, this.region);
const kService = await hmac(kRegion, this.service);
kCredentials = await hmac(kService, "aws4_request");
this.cache.set(cacheKey, kCredentials);
}
return buf2hex(await hmac(kCredentials, await this.stringToSign()));
}
async stringToSign() {
return [
"AWS4-HMAC-SHA256",
this.datetime,
this.credentialString,
buf2hex(await hash(await this.canonicalString()))
].join("\n");
}
async canonicalString() {
return [
this.method.toUpperCase(),
this.encodedPath,
this.encodedSearch,
this.canonicalHeaders + "\n",
this.signedHeaders,
await this.hexBodyHash()
].join("\n");
}
async hexBodyHash() {
let hashHeader = this.headers.get("X-Amz-Content-Sha256") || (this.service === "s3" && this.signQuery ? "UNSIGNED-PAYLOAD" : null);
if (hashHeader == null) {
if (this.body && typeof this.body !== "string" && !("byteLength" in this.body)) {
throw new Error("body must be a string, ArrayBuffer or ArrayBufferView, unless you include the X-Amz-Content-Sha256 header");
}
hashHeader = buf2hex(await hash(this.body || ""));
}
return hashHeader;
}
};
async function hmac(key, string) {
const cryptoKey = await crypto.subtle.importKey(
"raw",
typeof key === "string" ? encoder.encode(key) : key,
{ name: "HMAC", hash: { name: "SHA-256" } },
false,
["sign"]
);
return crypto.subtle.sign("HMAC", cryptoKey, encoder.encode(string));
}
async function hash(content) {
return crypto.subtle.digest("SHA-256", typeof content === "string" ? encoder.encode(content) : content);
}
function buf2hex(buffer) {
return Array.prototype.map.call(new Uint8Array(buffer), (x) => ("0" + x.toString(16)).slice(-2)).join("");
}
function encodeRfc3986(urlEncodedStr) {
return urlEncodedStr.replace(/[!'()*]/g, (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase());
}
function guessServiceRegion(url, headers) {
const { hostname, pathname } = url;
if (hostname.endsWith(".r2.cloudflarestorage.com")) {
return ["s3", "auto"];
}
if (hostname.endsWith(".backblazeb2.com")) {
const match2 = hostname.match(/^(?:[^.]+\.)?s3\.([^.]+)\.backblazeb2\.com$/);
return match2 != null ? ["s3", match2[1]] : ["", ""];
}
const match = hostname.replace("dualstack.", "").match(/([^.]+)\.(?:([^.]*)\.)?amazonaws\.com(?:\.cn)?$/);
let [service, region] = (match || ["", ""]).slice(1, 3);
if (region === "us-gov") {
region = "us-gov-west-1";
} else if (region === "s3" || region === "s3-accelerate") {
region = "us-east-1";
service = "s3";
} else if (service === "iot") {
if (hostname.startsWith("iot.")) {
service = "execute-api";
} else if (hostname.startsWith("data.jobs.iot.")) {
service = "iot-jobs-data";
} else {
service = pathname === "/mqtt" ? "iotdevicegateway" : "iotdata";
}
} else if (service === "autoscaling") {
const targetPrefix = (headers.get("X-Amz-Target") || "").split(".")[0];
if (targetPrefix === "AnyScaleFrontendService") {
service = "application-autoscaling";
} else if (targetPrefix === "AnyScaleScalingPlannerFrontendService") {
service = "autoscaling-plans";
}
} else if (region == null && service.startsWith("s3-")) {
region = service.slice(3).replace(/^fips-|^external-1/, "");
service = "s3";
} else if (service.endsWith("-fips")) {
service = service.slice(0, -5);
} else if (region && /-\d$/.test(service) && !/-\d$/.test(region)) {
[service, region] = [region, service];
}
return [HOST_SERVICES[service] || service, region];
}
// index.js
var UNSIGNABLE_HEADERS2 = [
"x-forwarded-proto",
"x-real-ip"
];
function filterHeaders(headers) {
return Array.from(headers.entries()).filter((pair) => !UNSIGNABLE_HEADERS2.includes(pair[0]) && !pair[0].startsWith("cf-"));
}
async function handleRequest(event, client2) {
const request = event.request;
if (!["GET", "HEAD"].includes(request.method)) {
return new Response(null, {
status: 405,
statusText: "Method Not Allowed"
});
}
const url = new URL(request.url);
let path = url.pathname.replace(/^\//, "");
path = path.replace(/\/$/, "");
const pathSegments = path.split("/");
if (ALLOW_LIST_BUCKET !== "true") {
if (BUCKET_NAME === "$path" && pathSegments[0].length < 2 || BUCKET_NAME !== "$path" && path.length === 0) {
return new Response(null, {
status: 404,
statusText: "Not Found"
});
}
}
switch (BUCKET_NAME) {
case "$path":
url.hostname = B2_ENDPOINT;
break;
break;
case "$host":
url.hostname = url.hostname.split(".")[0] + "." + B2_ENDPOINT;
break;
default:
url.hostname = BUCKET_NAME + "." + B2_ENDPOINT;
break;
}
const headers = filterHeaders(request.headers);
const signedRequest = await client2.sign(url.toString(), {
method: request.method,
headers,
body: request.body
});
return fetch(signedRequest);
}
var endpointRegex = /^s3\.([a-zA-Z0-9-]+)\.backblazeb2\.com$/;
var [, aws_region] = B2_ENDPOINT.match(endpointRegex);
var client = new AwsClient({
"accessKeyId": B2_APPLICATION_KEY_ID,
"secretAccessKey": B2_APPLICATION_KEY,
"service": "s3",
"region": aws_region
});
addEventListener("fetch", function(event) {
event.respondWith(handleRequest(event, client));
});
})();
/**
* #license MIT <https://opensource.org/licenses/MIT>
* #copyright Michael Hart 2022
*/
//# sourceMappingURL=index.js.map
[1]: https://github.com/backblaze-b2-samples/cloudflare-b2

Geoserver 2.17.2 WFS-T and WPS

I cannot manage to run WFS-T demos in GeoServer 2.17.2. In Demo always give an error. In a similar way, I want to run WPS demos but always got an error
coverage store not found
In the workspace I enabled WPS but I got no response coming from geoserver side.
HTTP response: 500 Server Error
Anyone know how can I run WFS-T demos in GeoServer ?
// Promises
var _eid_promises = {};
// Turn the incoming message from extension // into pending Promise resolving
window.addEventListener("message", function (event) {
if (event.source !== window) return;
if (event.data.src && (event.data.src === "background.js")) {
console.log("Page received: ");
console.log(event.data);
// Get the promise
if (event.data.nonce) {
var p = _eid_promises[event.data.nonce];
// resolve
if (event.data.result === "ok") {
if (event.data.signature !== undefined) {
p.resolve({
hex: event.data.signature
});
} else if (event.data.version !== undefined) {
p.resolve(event.data.extension + "/" + event.data.version);
} else if (event.data.cert !== undefined) {
p.resolve({
hex: event.data.cert
});
} else {
console.log("No idea how to handle message");
console.log(event.data);
}
} else { // reject
p.reject(new Error(event.data.result));
}
delete _eid_promises[event.data.nonce];
} else {
console.log("No nonce in event msg");
}
}
}, false);
function TokenSigning() {
function nonce() {
var val = "";
var hex = "abcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 16; i++) val += hex.charAt(Math.floor(Math.random() * hex.length));
return val;
}
function messagePromise(msg) {
return new Promise(function (resolve, reject) { // amend with necessary metadata
msg["nonce"] = nonce();
msg["src"] = "page.js";
// send message
window.postMessage(msg, "*");
// and store promise
callbacks _eid_promises[msg.nonce] = {
resolve: resolve,
reject: reject
};
});
}
this.getCertificate = function (options) {
var msg = {
type: "CERT",
lang: options.lang,
filter: options.filter
};
console.log("getCertificate()");
return messagePromise(msg);
};
this.sign = function (cert, hash, options) {
var msg = {
type: "SIGN",
cert: cert.hex,
hash: hash.hex,
hashtype: hash.type,
lang: options.lang,
info: options.info
};
console.log("sign()");
return messagePromise(msg);
};
this.getVersion = function () {
console.log("getVersion()");
return messagePromise({
type: "VERSION"
});
};
}

Axios post request not running in sequence

I am trying to make use of async series correctly but unable to figure how exactly i need to send the data into it for it to move forward with each post request in exactly the same way as it is getting data.
I have an excel file in which i am getting multiple statuses to mark against each ids that are present in the first column. Also there are statuses that need to be deleted and deleting part is not that difficult and i was able to do it without making use of async series but for posting new records I need to make use of async series. The records to be posted are under the columns 'Mark Status 1', 'Mark Status 1 Date', 'Mark Status 2' and so on. So i wrote a script to fetch the records using a for loop and send them off to a function and that function is responsible for modelling data for asyn series. Inside the markStatusCall function if i put a forEach loop and run the call the sequence of the statuses become wrong. It should be like 'Marks Status 1 value', 'Mark Status 2 value' and so on.
I am attaching my code here, please take a look below and to see the excel file here
const Excel = require("exceljs");
const axios = require("axios").default;
const https = require("https");
const _async = require("async");
const instance = axios.create({
httpsAgent: new https.Agent({
rejectUnauthorized: false,
}),
});
const returnedId = "5dd7fa20dcfa9600152cc2de";
const deliveredId = "5dd7fa20dcfa9600152cc2d3";
const returnedByVendorId = "5de7c418362e13001212f238";
const returnedToVendor = "5eb2ebfe02987816aad14269";
const atSwyftWarehouse = "5dd7fa20dcfa9600152cc2d8";
const reAttempted = "5e6ea5d87aa7bb6d726b2bbc";
const requestToReattempt = "5ee134230138634c27a6e1da";
const dispatched = "5dd7fa20dcfa9600152cc2e2";
const parcelAssignedDelivery = "5dd7fa20dcfa9600152cc2e3";
const cancelledByVendor = "5de7c418362e13001212f238";
var workbook = new Excel.Workbook();
workbook.xlsx.readFile("./1.xlsx").then(async function () {
// use workbook
var worksheet = workbook.getWorksheet("Interim");
const parcelIds = [];
const status = [];
const date = [];
var data = [];
var finalData = [];
for (let i = 2; i <= 10; i++) {
worksheet.getRow(i).eachCell((cell, index) => {
if (cell.value !== "") {
worksheet.getColumn(index).eachCell((colCell, indexing) => {
if (indexing === 1) {
if (colCell.value === "Delete Status 1") {
deleteData(i, cell);
} else if (colCell.value === "Delete Status 2") {
deleteData(i, cell);
} else if (colCell.value === "Delete Status 3") {
deleteData(i, cell);
} else if (colCell.value === "Delete Status 4") {
deleteData(i, cell);
} else if (colCell.value === "Delete Status 5") {
deleteData(i, cell);
} else if (colCell.value === "Mark Status 1") {
markData(i, index, cell);
} else if (colCell.value === "Mark Status 2") {
markData(i, index, cell);
} else if (colCell.value === "Mark Status 3") {
markData(i, index, cell);
} else if (colCell.value === "Mark Status 4") {
markData(i, index, cell);
} else if (colCell.value === "Mark Status 5") {
markData(i, index, cell);
}
}
});
}
});
}
function markData(i, index, cell) {
let row = worksheet.getRow(i);
let date = row.getCell(index + 1).value;
let parcelId = row.getCell(1).value;
if (cell.value !== "" && date !== "") {
let statusId =
cell.value === "At Swyft Warehouse"
? atSwyftWarehouse
: cell.value === "Dispatched"
? dispatched
: cell.value === "Reattempted"
? reAttempted
: cell.value === "Delivered"
? deliveredId
: cell.value === "Cancelled"
? returnedId
: cell.value === "Request for Reattempt"
? requestToReattempt
: cell.value === "Parcel Assigned"
? parcelAssignedDelivery
: cell.value === "Cancelled by Vendor"
? cancelledByVendor
: deliveredId;
console.log(parcelId, statusId, date);
addStatus(parcelId, statusId, date);
}
}
// Need help from here
function addStatus(parcelId, statusId, date) {
let values = {
parcelId: parcelId,
statusRepositoryId: statusId,
createdAt: date,
updatedByScript: true,
};
data.push(values);
}
finalData.push(() => markStatusCall(data));
_async.series(finalData, (err, data) => {
if (err) {
console.log(err);
}
});
async function markStatusCall(values) {
console.log(values, "Came here");
values.forEach((data) => {
try {
let response = await instance.post(
"https://api.myDomain.com:3000/api/ParcelStatuses",
{
parcelId: data.parcelId,
statusRepositoryId: data.statusRepositoryId,
createdAt: data.createdAt,
updatedByScript: data.updatedByScript,
}
);
console.log("Updated");
} catch (err) {
console.log("here");
console.error(err);
}
})
}
Would something like this work:
async function markStatusCall(values) {
console.log(values, "markStatusCall begin");
function loop(values, index) {
console.log('loop at index', index);
const data = {
parcelId: data.parcelId,
statusRepositoryId: data.statusRepositoryId,
createdAt: data.createdAt,
updatedByScript: data.updatedByScript};
try {
let response = await instance.post("https://api.myDomain.com:3000/api/ParcelStatuses", data);
console.log("Updated");
if (index <= (values.length -1)) {
loop(index + 1);
} else {
return;
}
} catch (err) {
console.log("Error");
console.error(err);
}
}
await loop(values, 0);
}
The idea is that the loop waits for each POST request before moving onto the next item in the values array. (might be some typos in the code above).
See this example on codepen
Try doing something like this
function markStatusCall(values) {
let promises=[];
values.forEach((data) => {
const promise = instance.post(
"https://api.myDomain.com:3000/api/ParcelStatuses",
{
parcelId: data.parcelId,
statusRepositoryId: data.statusRepositoryId,
createdAt: data.createdAt,
updatedByScript: data.updatedByScript,
});
return promises.push(promise);
})
Promise.all(promises).then(() => {
console.log('success')
}).catch(error => {
console.error(error.message)
});
}
This can still not ensure your order but it's highly recommended to use promises than async-await
The order of response will follow your order only if the latency for all the responses are same

NodeJS Cannot read property 'length' of undefined - MagicMirror Module

I'm working on a prototype of a MagicMirror Module that pulls data in from this json feed https://jsonplaceholder.typicode.com/todos/1. It passes fine on json parse payload But fails somewhere in within tArray length with cannot ready property 'length' of undefined. I'm suspecting the JSON isn't being carried to tArray properly, but i'm a at a loss. Below are my two files!
node_helper.js
'use strict';
/* Magic Mirror
* Module:
*/
const NodeHelper = require('node_helper');
var request = require('request');
var moment = require('moment');
module.exports = NodeHelper.create({
start: function() {
this.started = false;
this.config = null;
},
getData: function() {
var self = this;
var myUrl = "https://jsonplaceholder.typicode.com/todos/1";
request({
url: myUrl,
method: 'GET',
headers: { 'API_TOKEN': this.config.apiKey }
}, function (error, response, body) {
console.log(body);
if (!error && response.statusCode == 200) {
self.sendSocketNotification("DATA", body);
}
});
setTimeout(function() { self.getData(); }, this.config.refreshInterval);
},
socketNotificationReceived: function(notification, payload) {
var self = this;
if (notification === 'CONFIG' && self.started == false) {
self.config = payload;
self.sendSocketNotification("STARTED", true);
self.getData();
self.started = true;
}
}
});
MMM-Fi.js
/* Magic Mirror
*/
Module.register('MMM-Fi',{
defaults: {
animationSpeed: 1000,
refreshInterval: 1000 * 60, //refresh every minute
updateInterval: 1000 * 3600, //update every hour
lang: config.language,
initialLoadDelay: 0, // 0 seconds delay
retryDelay: 5,
},
// Define required scripts.
getScripts: function() {
return ["moment.js", "font-awesome.css"];
},
getStyles: function() {
return ['MMM-Fi.css'];
},
start: function() {
Log.info('Starting module: ' + this.name);
this.loaded = false;
this.sendSocketNotification('CONFIG', this.config);
},
getDom: function() {
var wrapper = document.createElement("div");
if (this.config.apiKey === "") {
wrapper.innerHTML = "No Fi <i>apiKey</i> set in config file.";
wrapper.className = "dimmed light small";
return wrapper;
}
if (this.config.googleApiKey === "") {
wrapper.innerHTML = "No Google <i>api Key</i> set in config file.";
wrapper.className = "dimmed light small";
return wrapper;
}
if (!this.loaded) {
wrapper.innerHTML = this.translate('LOADING');
wrapper.className = "dimmed light small";
return wrapper;
}
if (!this.tArray.length) {
wrapper.innerHTML = "No data";
wrapper.className = "dimmed light small";
return wrapper;
}
var table = document.createElement("table");
table.id = "fitable";
table.className = "small thin light";
var row = document.createElement("tr");
var lineHeader = document.createElement("th");
lineHeader.innerHTML = "test2";
lineHeader.colSpan = 2;
row.appendChild(lineHeader);
table.appendChild(row);
for (var i in this.tArray) {
var currentDeparture = this.tArray[i];
console.log(currentDeparture.title)
}
wrapper.appendChild(table);
return wrapper;
},
tFi: function(data) {
if (!data.listT) {
return;
}
this.tArray = [];
for (var i in data.listT) {
var t = data.listT[i];
this.tArray.push({
userId: t.userId,
id: t.id,
title: t.title,
completed: t.completed,
});
}
return;
},
socketNotificationReceived: function(notification, payload) {
if (notification === "STARTED") {
this.updateDom();
}
else if (notification === "DATA") {
this.loaded = true;
this.tFi(JSON.parse(payload));
this.updateDom();
}
}
});

could not use find to get specific array element that satisfy my function

so I have a selector that contains multiple options and below that I have a paragraph the content of which would change in accordance to the selected option in the select menu. I used find method to loop through the array and return the element(which is an object) that satisfy find function. however there is a problem with find method that I could not figure out.
'use strict';
{
function fetchJSON(url, cb) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onload = () => {
if (xhr.status < 400) {
cb(null, xhr.response);
} else {
cb(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`));
}
};
xhr.onerror = () => cb(new Error('Network request failed'));
xhr.send();
}
function createAndAppend(name, parent, options = {}) {
const elem = document.createElement(name);
parent.appendChild(elem);
Object.keys(options).forEach(key => {
const value = options[key];
if (key === 'text') {
elem.textContent = value;
} else {
elem.setAttribute(key, value);
}
});
return elem;
}
function createLI(root, sel, options = []) {
const select = document.createElement(sel);
root.appendChild(select);
select.innerHTML = options.sort().map(repo => `<option value="${repo.id}">${repo.name}</option>`).join('\n');
select.addEventListener("change", function () {
const chosenRepoId = this.value;
const selectedRepo = options.find(repo => repo.id === chosenRepoId);
document.getElementById('repoInfo').innerHTML = selectedRepo.description;
});
}
function main(url) {
fetchJSON(url, (err, data) => {
const root = document.getElementById('root');
if (err) {
createAndAppend('div', root, { text: err.message, class: 'alert-error' });
} else {
// createAndAppend('pre', root, { text: JSON.stringify(data, null, 2) });
createLI(root, 'select', data);
}
});
}
const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100';
window.onload = () => main(HYF_REPOS_URL);
}
````js
this.value returns string.
In the comparison - const selectedRepo = options.find(repo => repo.id === chosenRepoId);
you are using strict equality operator and your chosenRepoId is numeric. So, first convert the selected value to number (use + or parseInt).
const chosenRepoId = +this.value;
const selectedRepo = options.find(repo => repo.id === chosenRepoId);

Categories