javascript for loop with API request - javascript

I'm used to PHP, doing first thing in js/nodejs. I guess this is some sync/async problem. I have array of currencies and trying to do a for loop with API call. In output you can see three different json outputs (different order everytime) but when I am trying to save the value in the file, I get only the last one from array. Also the var c has same value in console logs (TESTBTC)
array:
TESTUSDT,TESTUSD,TESTBTC,
code:
const axios = require('axios');
const fs = require('fs');
var currencies = (fs.readFileSync('funding_currencies.txt', 'utf-8'));
const currencies_array = currencies.split(",");
for (i = 0; i < currencies_array.length - 1; i++) {
var c = currencies_array[i];
if (fs.existsSync('frr_' + c + '.txt')) {
var oldfrr = (fs.readFileSync('frr_' + c + '.txt', 'utf-8'));
fs.writeFile("frr_" + c + "_old.txt", oldfrr, function (err) {
if (err) {
return console.log(err);
}
});
}
console.log("funding/stats/" + c + "/hist");
var baseUrl = "https://api-pub.bitfinex.com/v2/";
var pathParams = "funding/stats/f" + c + "/hist";
var queryParams = "limit=1";
axios.get(`${baseUrl}/${pathParams}?${queryParams}`)
.then(response => {
console.log(response.data);
var raw = JSON.stringify(response.data);
var partsArray = raw.split(',');
var frr = 100 * 365 * partsArray[3];
console.log(c + ' - Daily Rate % FRR: ' + frr);
fs.writeFile("frr_" + c + ".txt", frr, function (err) {
if (err) {
return console.log(err);
}
console.log("FRR for " + c + " saved to file");
});
}, error => {
console.log(error);
})
}
output:
funding/stats/TESTUSDT/hist
funding/stats/TESTUSD/hist
funding/stats/TESTBTC/hist
[
[
1675598700000, null,
null, 0.00000128,
39.56, null,
null, 748236.20624443,
676828.07200483, null,
null, 10865216.1584813
]
]
TESTBTC - Daily Rate % FRR: 0.04672
[
[
1675598700000, null,
null, 0.00002035,
69.88, null,
null, 519081.88192342,
519081.08203316, null,
null, 0
]
]
TESTBTC - Daily Rate % FRR: 0.742775
[
[
1675598700000, null,
null, 0.00000386,
28.31, null,
null, 6372417.33205204,
6372417.33205204, null,
null, 0
]
]
TESTBTC - Daily Rate % FRR: 0.14089000000000002
FRR for TESTBTC saved to file
FRR for TESTBTC saved to file
FRR for TESTBTC saved to file
So I need to save the values in right associations in right files

You have only one variable c, which is accessed by all the asynchronous response => {...} functions spawned by the axios.get statements. Because of their asynchronousness, all these functions will see the last value that c takes.
To get one variable per execution, replace the for loop with the following:
currencies_array.forEach(function(c) {
if (fs.existsSync('frr_' + c + '.txt')) {
...
}

Related

POST request cypress for-loop

I'm writing a script to test automatic. First I create a shipment with random items. After that I make a POST request. Everything is working fine, but the POST request keeps giving the same data. But my console prints other data.
Does anybody know what I am doing wrong? Is it maybe impossible to do POST requests in a for loop?
/// <reference types="cypress" />
describe('Create random shipments, Sign in, scan items, to transit', () => {
beforeEach(() => {
cy.visit('http://localhost:3000/')
})
it('Sign in, scan items, to transit', () => {
const username = '<username>'
const password = '<password>'
// Create default shipment
const shipmentText = '{'+
'"content": [],' +
'"date": "2022-05-05",' +
'"sender": { "company": "61d609e319b2c600129f71bb", "location": "61d609e319b2c600129f71bc" },' +
'"receiver": {},' +
'"orderNumber": "123456-20",' +
'"transportNumber": "TransportNumber {{routeNaam}}",' +
'"transportStopNumber": "Stop1",' +
'"note": "<noteText>"}';
const shipment = JSON.parse(shipmentText);
// Create locations Test20, Test19, Test17
const text = '{"locations":[' +
'{"company": "6228be12e4a3460011f94c13","location": "6228be12e4a3460011f94c14"},' +
'{"company": "6228a461e4a3460011f94676","location": "6228a461e4a3460011f94677"}]}';
const objLocations = JSON.parse(text);
// Create coreItems from .....
const itemText = '{"items":[' +
'{"coreItem": "6138c0ec64f3ea001196e5aa","quantity": 0,"status": "WHOLE","uniqueIds": []},' +
'{ "coreItem": "6138bff564f3ea001196e540", "quantity": 0, "status": "WHOLE", "uniqueIds": [] },' +
'{ "coreItem": "6138bfa464f3ea001196e51c", "quantity": 0, "status": "WHOLE", "uniqueIds": [] },' +
'{ "coreItem": "619e4fe2485d2b00112d0262", "quantity": 0, "status": "WHOLE" }]}';
const objItems = JSON.parse(itemText);
const laagCoreId = "6138c0ec64f3ea001196e5aa"
const middelCoreId = "6138bff564f3ea001196e540"
const hoogCoreId = "6138bfa464f3ea001196e51c"
const opzetCoreId = "619e4fe2485d2b00112d0262"
// Loop through the different companies
for (let i = 0; i < Object.values(objLocations.locations).length; i++) {
// Get company id and location
const element = Object.values(objLocations.locations)[i];
cy.log("company:" + element.company, "location:" + element.location)
// Loop through different coreItems
for (let i = 0; i < Object.values(objItems.items).length; i++) {
// Create random quantity between 1 - 10
Object.values(objItems.items)[i].quantity = Math.floor(Math.random() * 10) + 1;
let uids = []
let qty = 0
// Check item
// Create for each quantity a uid
if (Object.values(objItems.items)[i].coreItem == laagCoreId) {
qty = parseInt(Object.values(objItems.items)[i].quantity)
for (let i = 0; i < qty; i++) {
let uid = 20000000+Math.floor(Math.random() * 1000000) + 1;
uids.push(String(uid))
}
}
else if (Object.values(objItems.items)[i].coreItem == middelCoreId) {
qty = parseInt(Object.values(objItems.items)[i].quantity)
for (let i = 0; i < qty; i++) {
let uid = 30000000+Math.floor(Math.random() * 1000000) + 1;
uids.push(String(uid))
}
}
else if (Object.values(objItems.items)[i].coreItem == hoogCoreId) {
qty = parseInt(Object.values(objItems.items)[i].quantity)
for (let i = 0; i < qty; i++) {
let uid = 40000000+Math.floor(Math.random() * 1000000) + 1;
uids.push(String(uid))
}
}
// Add uids array to coreItems
Object.values(objItems.items)[i].uniqueIds = uids
}
// Copy shipment
let copyShipment = shipment
// Change content to coreItems with qty and uids
copyShipment.content = objItems.items
// Cange receiver
copyShipment.receiver = Object.values(objLocations.locations)[i]
cy.log(JSON.stringify(copyShipment))
cy.request({
method: 'POST',
url: '<url>',
headers: {
'Content-Type': 'application/json',
'api-token' : '<token>',
},
body: copyShipment
})
.should(
(response) => {
expect(response.status).to.eq(200)
},
)
.then(
(response) => {
cy.log(JSON.stringify(response))
}
)
}
})
})
For loops don't work nicely with asynchronous commands like cy.request(), but without running it I would expect the code you have to work.
One quick trick to try is to wrap the cy.request() in a cy.then(). This defers the request setup and hopefully gives you the correct copyShipment value each time.
...
cy.log(JSON.stringify(copyShipment))
cy.then(() => {
cy.request({
method: 'POST',
url: '<url>',
headers: {
...
},
body: copyShipment
})
.should(...)
})

Cosmos DB stored procedure

I'm trying to run a procedure which queries documents and adjusts some properties according to some rules which are decided by the parameters that I pass to the query.
function downsample(ageInDays, downsampleFactor) {
var collection = getContext().getCollection();
var responseBody = {
deleted: 0,
message: ""
};
var downsampledDocuments = [];
var count = 0;
collection.queryDocuments(
collection.getSelfLink(),
'SELECT * FROM root r ' +
'WHERE (DATEDIFF(day, r.EventProcessedUtcTime, GETDATE()) > ' + ageInDays+ 'AND r.downsamplingFactor < ' + downsampleFactor + ')' +
'OR' +
'((DATEDIFF(day, r.EventProcessedUtcTime, GETDATE()) > ' + ageInDays + ' AND r.downsamplingFactor = null )' +
'ORDER BY r.did, r.resourceType ASC',
function (err, documents, options) {
if (err) throw err;
// Check the feed and if empty, set the body to 'no docs found', 
// else perform the downsampling
if (!documents || !documents.length) {
var response = getContext().getResponse();
responseBody.message = "No documents found";
response.setBody(responseBody);
} else {
// We need to take into consideration that in a lot of cases, the data will already be downsampled so we
// example: previous downsampling factor of documents: 4, if a new downsampling is performed on these docs with factor 8 then we need to
var adjustedDownSamplingFactor;
if (documents[0].downsamplingFactor == null) {
adjustedDownSamplingFactor = downsampleFactor;
} else {
adjustedDownSamplingFactor = downsampleFactor / documents[0].downsamplingFactor;
}
var aggregatedDocument = documents[0];
var documentValueSum = 0;
var documentCount = 0;
var aggregatedDocumentValue = 0;
for(doc in documents){
if(!aggregatedDocument){
aggregatedDocument = doc;
}
if(documentCount >= adjustedDownSamplingFactor || aggregatedDocument.did !== doc.did || aggregatedDocument.resourceType !== doc.resourceType){
// preparing aggregated document
aggregatedDocumentValue = documentValueSum / documentCount;
aggregatedDocument.value = aggregatedDocumentValue;
aggregatedDocument.downsamplingFactor = downsampleFactor;
//Adding the downsampled data to the Array which will be uploaded to the cosmosdb
downsampledDocuments.push(aggregatedDocument);
aggregatedDocument = null;
documentCount = 0;
documentValueSum = 0;
continue;
}
documentValueSum += doc.value;
documentCount++;
}
var response = getContext().getResponse();
tryDelete(documents);
// Call the CRUD API to create a document.
tryCreate(downsampledDocuments[count], callback);
responseBody.message = "Downsampling was succesful"
response.setBody(responseBody);
}
});
So I'm not passing any documents to the query so I don't know which partition key I would have to supply to the stored procedure. Is there any way in which I can avoid having to supply a partition key? I'm calling this stored procedure from an API but keep getting a message that I should supply a partition key.
Is there any way in which I can avoid having to supply a partition
key?
Unfortunately no. You have to supply a partition key value.

Twitter API with node.js, get a list of followers

Hi I'm currently working on a Twitter bot with the Twitter API and Node.JS. I want the bot to return all of my followers and some of their features in an javascript object. Something like :
{['id', 'screen_name', 'name', 'screen_name', 'followers_count',
'friends_count']}
RN my code is :
var Twitter = new TwitterPackage(config);
var options =
{
screen_name: 'mowsolicious',
};
Twitter.get('followers/ids', options, function (err, data) { // returns a list of ids
var nbFollowers = data.ids.length
var id = []
console.log(nbFollowers) // how many followers I have
for (i=0 ; i <= nbFollowers ; i++) {
ids = data.ids
var id = ids[i]
Twitter.get('users/show/' + id, function(err, data) {
console.log(id + " - " + data.name + " - " + data.screen_name + " - " + data.followers_count + " - " + data.friends_count)
})
}
})
I'm pretty sure something is terribly wrong with my method (more precisely when I put the Twitter.get thing in the loop) and it returns a bunch of undefined in the console.
I tried to work with the API doc but I'm experiencing some troubles understanding it. If someone could help that would be great.
Thank you
Most likely, you get undefined because the user is not found :
[ { code: 50, message: 'User not found.' } ]
Checking err variable would take care of that. But looking at GET followers/id documentation, you should use GET users/lookup to efficiently request mutliple user objects (up to 100 user per request with user id delimited by comma)
Also, I assume you'd like a unique callback to be called when all requests are completed, using Promises will take care of that :
var res_array = [];
function getUserInfo(id_list) {
return Twitter.get('users/lookup', {
"user_id": id_list
}).then(function(data) {
res_array.push(data);
})
.catch(function(error) {
throw error;
})
}
Twitter.get('followers/ids', function(err, data) {
if (err) {
console.log(err);
return;
}
console.log("total followers : " + data.ids.length);
var requestNum = Math.floor(data.ids.length / 100);
var remainder = data.ids.length % 100;
var promises_arr = [];
for (var i = 0; i < requestNum; i++) {
promises_arr.push(getUserInfo(data.ids.slice(i * 100, i * 100 + 100).join(",")));
}
if (remainder != 0) {
promises_arr.push(getUserInfo(data.ids.slice(requestNum * 100, requestNum * 100 + 100).join(",")));
}
Promise.all(promises_arr)
.then(function() {
for (var i in res_array) {
for (var j in res_array[i]) {
var user = res_array[i][j];
console.log(user.id + " - " +
user.name + " - " +
user.screen_name + " - " +
user.followers_count + " - " +
user.friends_count)
}
}
})
.catch(console.error);
})
List of followers can be retrieved with superface sdk , try it based on the example below
npm install #superfaceai/one-sdk
npx #superfaceai/cli install social-media/followers
const { SuperfaceClient } = require('#superfaceai/one-sdk');
const sdk = new SuperfaceClient();
async function run() {
// Load the installed profile
const profile = await sdk.getProfile('social-media/followers');
// Use the profile
const result = await profile
.getUseCase('GetFollowers')
.perform({
profileId: '429238130'
});
return result.unwrap();
}
run();
This works pretty fine
import fetch from 'node-fetch'
async function getFollowers(username) {
const response = await fetch(`https://api.twitter.com/1.1/followers/list.json?screen_name=${username}`, {
headers: {
Authorization: `Bearer ${<yourbearertoken>}`
}
});
// Parse the response as JSON
const data = await response.json();
return data.users;
}
const followers = await getFollowers("<username>");

Which headers do I have to pass on an JavaScript S3 AWS request using signature v4 and assumed role credentials?

I'm trying to make a REST connection to Amazon S3 and I'm struggling to implement the signature V4 process. I know, Amazon also provides a JavasScript an sdk, but I need to get it to work by myself.
To test my code, I'm using the AWS testsuite and my code successfully returns the expected results. However, all my real life attempts fail because of signature does not match error.
The issue for me is, the examples don't include any headers except host and date which is kind of straightforward. I'm having to pass the "full monty" including access tokens and I'm sure there is a problem with the headers.
Here is what I'm doing on click of a button:
function simpleS3Scenario(my_storage) {
return new RSVP.Queue()
.push(function () {
return my_storage.allDocs();
})
.push(function (my_alldocs_response) {
console.log("initial ALLDOCS")
console.log(my_alldocs_response);
})
...
};
allDocs will eventually run into this:
S3Storage.prototype.buildQuery = function (param, options) {
var context = this,
url = this._base_url,
url_path = this._bucket + "/",
headers,
requestText;
return new RSVP.Queue()
.push(function () {
return SigV4_custom.makeSignedRequest(
"GET",
url + url_path,
'',
{"max-key": 100, "prefix": "sample_folder"},
{},
context._region,
"s3",
"AWS4-HMAC-SHA256",
context._secret_access_key,
context._access_key,
context._session_token
);
})
.push(function (e) {
console.log("YUPI");
console.log(e);
})
...
which enters my request signature handler, which is based on this (not working with Signature v4) Amazon example | code: sigv4.js:
(sorry, not shortened yet, scroll down to ENTRY POINT, then work yourself up)
var SigV4_custom = new function(){
this.createCanonicalRequest = function(){};
this.createStringToSign = function(){};
this.generateSignatureAndSign = function(){};
this.makeSignedRequest = function(){};
}
// trim polyfill
String.prototype.trim = String.prototype.trim || function () {
var start = -1,
end = this.length;
while( this.charCodeAt(--end) < 33 );
while( this.charCodeAt(++start) < 33 );
return this.slice( start, end + 1 );
};
// =============== generator funtions =================
// generate query parameter string for canonical request
function generateCanonicalQueryString(my_parameter_dict) {
var canonical_query_string = '',
encoded_parameter_dict = {},
key_list = [],
key,
value,
i,
i_len;
// set and encode
for (key in my_parameter_dict) {
if (my_parameter_dict.hasOwnProperty(key)) {
value = my_parameter_dict[key];
if (typeof value === "object") {
encoded_parameter_dict[encodeURIComponent(key)] =
encodeURIComponent(value[0]) + '&';
// Append each additional value to the query parameter
for (i = 0, i_len = value.length; i < i_len; i += 1) {
encoded_parameter_dict[encodeURIComponent(key)] +=
encodeURIComponent(key) + '=' + encodeURIComponent(value[i]) +'&';
}
encoded_parameter_dict[encodeURIComponent(key)] =
encoded_parameter_dict[encodeURIComponent(key)].slice(0,-1);
} else {
encoded_parameter_dict[encodeURIComponent(key)] =
encodeURIComponent(value);
}
}
}
// then fill key_list
for (key in encoded_parameter_dict) {
if (encoded_parameter_dict.hasOwnProperty(key)) {
key_list.push(key);
}
}
key_list.sort();
for (i = 0, i_len = key_list.length; i < i_len; i += 1) {
canonical_query_string +=
key_list[i] + "=" + encoded_parameter_dict[key_list[i]] + "&";
}
return canonical_query_string.slice(0, -1);
}
// generate canonical header string
function generateCanonicalHeaderString(my_header_dict, is_signature) {
var canonical_header_string = '',
encoded_header_dict = {},
header_list = [],
header,
value,
trimmed_value,
header_lowercase,
i,
i_len,
separator,
connector,
format,
cutoff;
if (is_signature) {
cutoff = -1;
separator = ":";
connector = "\n";
format = function (my_value) {
return my_value.toLowerCase();
}
} else {
cutoff = -1;
separator = "=";
connector = "&";
format = function (my_value) {
return my_value;
}
}
// Take header keys and put in array, then sort and build
for (header in my_header_dict) {
if (my_header_dict.hasOwnProperty(header)) {
header_lowercase = format(header);
value = my_header_dict[header];
trimmed_value = undefined;
//XXX there are not only strings in the headers...
if (value.trim) {
trimmed_value = value.trim();
}
if (encoded_header_dict[header_lowercase] === undefined) {
encoded_header_dict[header_lowercase] = trimmed_value || value;
header_list.push(header_lowercase);
} else {
encoded_header_dict[header_lowercase] += "," + trimmed_value || value;
}
}
}
header_list.sort();
for (i = 0, i_len = header_list.length; i < i_len; i += 1) {
canonical_header_string +=
header_list[i] +
separator +
encoded_header_dict[header_list[i]] +
connector;
}
canonical_header_string = canonical_header_string.slice(0, cutoff);
return canonical_header_string;
}
// generate the signed header string
function generateSignedHeaderString(my_header_dict) {
var signed_header_string = '',
header_list = [],
header,
header_lowercase,
i,
i_len;
for (header in my_header_dict) {
if (my_header_dict.hasOwnProperty(header)) {
header_list.push(header.toLowerCase());
}
}
header_list.sort();
for (i = 0, i_len = header_list.length; i < i_len; i += 1) {
signed_header_string += header_list[i] + ';';
}
return signed_header_string.slice(0, -1);
}
// returns a timestamp in the YYYYMMDD'T'HHmmSS'Z' format, for SigV4 calls
function generateTimestamp() {
var date = new Date();
function bump(my_time_parameter) {
if (my_time_parameter.length === 1) {
return '0' + my_time_parameter;
}
return my_time_parameter;
}
// Assemble date, bump single digits to doubles
// validation: return "20130524T000000Z";
return date.getUTCFullYear() +
bump((date.getUTCMonth()+1).toString()) + // month
bump(date.getUTCDate().toString()) + // day
'T' +
bump(date.getUTCHours().toString()) + // hour
bump(date.getUTCMinutes().toString()) + // minute
bump(date.getUTCSeconds().toString()) + // second
'Z';
}
// generate the credential scope
function generateCredentialScope(my_timestamp, my_region, my_service) {
return my_timestamp.substring(0, 8) + "/" +
my_region + "/" +
my_service + "/" +
"aws4_request";
}
// ================== CORE methods ==================
SigV4_custom.createStringToSign = function (request_time, credential_scope,
canonical_request, signing_algorithm) {
// Step 1: designate the algorithm (for SigV4 it is SHA256)
// Step 2: designate the RequestDate (already done, passed to function)
// Step 3: create credentialScope (already done, passed to funtion)
return signing_algorithm + '\n' +
request_time + '\n' +
credential_scope + '\n' +
canonical_request;
}
SigV4_custom.generateSignatureAndSign = function(secret, request_time, region,
service, string_to_sign) {
var datestamp = request_time.substring(0, 8),
hash_date,
hash_region,
hash_service,
hash_signing,
request = 'aws4_request';
hash_date = CryptoJS.HmacSHA256(datestamp, 'AWS4' + secret, {asBytes: true});
hash_region = CryptoJS.HmacSHA256(region, hash_date, {asBytes: true});
hash_service = CryptoJS.HmacSHA256(service, hash_region, {asBytes: true});
hash_signing = CryptoJS.HmacSHA256(request, hash_service, {asBytes: true});
// sign and return
return CryptoJS.HmacSHA256(string_to_sign, hash_signing)
.toString(CryptoJS.enc.Hex);
}
SigV4_custom.createCanonicalRequest = function(method, pathname,
parameter_dict, header_dict, hashed_payload) {
var canonical_request = "",
http_request_method = "",
canonical_url = "",
canonical_query_string = "",
canonical_header_string = "",
signed_header_string = "",
payload;
// Step 1: Start with the HTTP request method
http_request_method = method;
// Step 2: Add the canonicalUrl parameter
canonical_url = pathname;
// Step 3: Add the canonicalQueryString parameter
canonical_query_string = generateCanonicalQueryString(parameter_dict);
// Step 4: Add the canonicalHeaders parameter
canonical_header_string = generateCanonicalHeaderString(header_dict, true);
// Step 5: Add the signedHeaders parameter
signed_header_string = generateSignedHeaderString(header_dict);
// Step 6: Add the hashed payload
payload = hashed_payload;
// Step 7: string together the canonicalRequest from steps 1 through 6
canonical_request += http_request_method + '\n' +
canonical_url + '\n' +
canonical_query_string + '\n' +
canonical_header_string + '\n\n' +
signed_header_string + '\n' +
payload;
return canonical_request;
};
// =================== ENTRY POINT ===================
// Call this function to make a SigV4 REST API call.
SigV4_custom.makeSignedRequest = function (method, path, payload,
parameter_dict, header_dict, region, service, signing_algorithm,
secret_access_key, access_key_id, security_token) {
var link = document.createElement("a"),
request_time = generateTimestamp(),
scope = generateCredentialScope(request_time, region, service),
authorization_string,
canonical_request,
string_to_sign,
request_uri,
signature;
// link is a location object, set its href to use its properties
link.href = path;
// set all headers, then generate a canonical_request
// payload must be hashed here, as this may vary and the hash is required
// for canonization and as a header. Empty payloads will hash an empty "".
header_dict['X-Amz-Content-Sha256'] = CryptoJS.SHA256(payload)
.toString(CryptoJS.enc.Hex);
header_dict['host'] = link.hostname;
header_dict['X-Amz-Date'] = request_time;
header_dict['X-Amz-Credential'] = access_key_id + "/" + scope;
header_dict['X-Amz-Security-Token'] = security_token;
header_dict['X-Amz-Algorithm'] = signing_algorithm;
header_dict['X-Amz-Expires'] = 86400;
// Task 1: Compute the canonical request
canonical_request = CryptoJS.SHA256(
this.createCanonicalRequest(
method,
link.pathname,
parameter_dict,
header_dict,
header_dict['X-Amz-Content-Sha256']
)
)
.toString(CryptoJS.enc.Hex);
// delete host because it is also in the headers (needs to be in both
// initially to create the canonicalization)
delete parameter_dict['host'];
// Task 2: Create the string to sign using the encoded canonical request
string_to_sign = this.createStringToSign(
request_time,
scope,
canonical_request,
signing_algorithm
);
// Task 3: Create the signature using the signing key and the string to sign
signature = this.generateSignatureAndSign(
secret_access_key,
request_time,
region,
service,
string_to_sign
);
// Task 4: Build the authorization header
header_dict['Authorization'] = header_dict['X-Amz-Algorithm'] +
" Credential=" + header_dict['X-Amz-Credential'] + "," +
"SignedHeaders=" + generateSignedHeaderString(header_dict) + "," +
"Signature=" + signature;
// Task 5: Make the request (through jIO)
return new RSVP.Queue()
.push(function () {
return jIO.util.ajax({
"method": method,
"url": path,
"headers": header_dict
});
});
}
So when I run the Amazon samples with just two headers through this, I get correct signature and authorization header at the end. I believe I'm doing something wrong with the headers, especially which headers should go into the signature, but I can't find any good help online and am stuck on this for a few days now.
Question:
Maybe someone has an idea from looking at how I'm handling the headers, why my requests to AWS fail due to non-matching signature?
THANKS!
Edit:
I have used this Amazon Example page for deriving signatures. If I run the sample inputs through my createSignatureAndSign method, I can produce the same outputs. So my signature is correct an secret are correct.

Windows 8 Application Javascript and SQlite (Database is locked)

I write some simple app for windows 8 Metro UI with javascript. Because natural method from microsoft to use Sqlite with Javascript in Metro UI. I use 'doo' wrapper:
dooWrapper SQLite (github)
I create a method :
function addSomething(name) {
var dbPath = Windows.Storage.ApplicationData.current.localFolder.path + '\\a_db.sqlite';
SQLite3JS.openAsync(dbPath).then(function (db) {
return db.runAsync("INSERT INTO STH (nazwa) VALUES (:name)", { name: name }).
done(function () {
console.log('Add sth : ' + name);
db.close();
}, function (error) {
if (db) {
db.close();
}
console.log('ERROR Adding sth' + error.message);
})
});
}
I get error 'database is locked' I read about this error in documentation. But I have one question is other solution to add more rows without create 'insert' function with collections argument something like that : insert (array) ? I just want to use that function n-times without this error. That's possible?
Yes,it possible...i also got this error before....For that you just need to establish the database connection once...i have used this in my app and its working fine.
If there is no need of closing your db then then open database once like..
Add this code to default.js file
var myDatabase; //Global Variable
var dbPath = Windows.Storage.ApplicationData.current.localFolder.path + '\\db.sqlite';
//Create Table
SQLite3JS.openAsync(dbPath).then(function(db) {
myDatabase=db;
return db.runAsync('CREATE TABLE Item (name TEXT, price REAL, id INT PRIMARY KEY)');
});
Then you just need to use below code
// For Insert
return myDatabase.runAsync('INSERT INTO Item (name, price, id) VALUES ("'+ array[i].name+'", "48484", 1);
For array
var dbPromises = [];
var testArray = [];
//only for test purpose
//You can pass your array here directly
for (var a = 0; a < 300; a++) {
var obj = {
name: "Mango"+a,
price: 100+a,
id: a
};
testArray.push(obj);
}
for (var i = 0; i < testArray.length; i++) {
var query = 'INSERT OR REPLACE INTO Item (name, price, id) VALUES ("' + testArray[i].name + '",' + testArray[i].price + ',' + testArray[i].id + ')';
dbPromises.push(globalDatabase.allAsync(query));
}
WinJS.Promise.join(dbPromises).then(function () {
debugger;
}, function(err) {
debugger;
});
Above code is used only for less array size...bcz its taking too much time for insertion...
For fasst execution you should replace just below code
for (var i = 0; i < testArray.length; i++) {
var val = '("' + testArray[i].name + '",' + testArray[i].price + ',' + testArray[i].id + '),';
query = query + val;
if ((i + 1) % 300 == 0 || (i + 1) == testArray.length) {
query = query.replace(/,$/, "");
dbPromises.push(globalDatabase.allAsync(query));
query = 'INSERT OR REPLACE INTO Item (name, price, id) VALUES ';
}
}

Categories