Switched from Atom code editor to PHP Storm, and a lot of my code is being highlighted when I use promises with the following message: Expression statement is not assignment or call
Here is an example of some highlighted code:
getTickers.bitfinex = function() {
var counter = 0,
promises = []
//highlighted code begins here
new Promise(function(resolve, reject) {
request.get({
url: 'https://api.bitfinex.com/v1/symbols'
},
function(err, res, body) {
if (err) {
console.log(err, 'bitfinex api error')
reject(err, 'bitfinex api error')
}
if (!err) {
body = JSON.parse(body)
var symbols = []
body.forEach(function(symbol) {
symbol = 't' + symbol.toUpperCase()
symbols.push(symbol)
})
resolve(symbols)
}
})
})
.then((symbols) => {
var symbolsStr = symbols.join()
request.get({
url: 'https://api.bitfinex.com/v2/tickers?symbols=' + symbolsStr
},
function(err, res, body) {
body = JSON.parse(body)
if (err) {
console.log(err, 'bitfinex api error')
}
if (body[0] == 'error') {
console.log(body, 'bitfinex api error')
}
if (body[0] !== 'error') {
body.forEach(function(ticker) {
var promise = new Promise(function(resolve, reject) {
var currencyPair = ticker[0].replace("t", ""),
splitCurrencies = currencyPair.match(/[A-Z]{3}/g),
baseCurrency = splitCurrencies[0],
quoteCurrency = splitCurrencies[1]
Ticker.create({
currency_pair: baseCurrency + '-' + quoteCurrency,
base_currency: baseCurrency,
quote_currency: quoteCurrency,
last: ticker[7],
volume: ticker[8],
native_currency_pair: ticker[0],
exchange: 'bitfinex',
time: new Date().getTime()
}, function(err, document) {
if (err) {
reject(err)
}
if (document) {
counter++
resolve()
}
})
})
promises.push(promise)
})
Promise.all(promises)
.then(() => console.log(counter + ' bitfinex tickers updated'))
.catch((err) => console.log(err, 'bitfinex update error'))
}
})
})
.catch((err) => console.log(err))
//highlight ends here
}
What can I add or change in the code to make this correct so the warning goes away?
In order to disable this WebStorm-specific code inspection go to
WebStorm -> Preferences -> Editor -> Inspections
and uncheck the box under JavaScript -> JavaScript validity issues
that has the label, "expression statement which is not assignment or call".
If you would like to actually change your code to fix these errors, see this answer.
Related
I'm new to NodeJS so please apologize if below code is not up-to the standard. I would like to access isSuccess value outside of this function stepfunctions.listExecutions
I tried below code but I'm getting the value is undefined not getting the expected output. I did some internet search and came to know in NodeJS we can't set the value which is defined in globally but I've use case and I'm pretty sure this is a common case for others too - where I would like to access this isSuccess value after my execution.
const AWS = require('aws-sdk');
const stepfunctions = new AWS.StepFunctions({
region: process.env.AWS_REGION
});
var params = {
stateMachineArn: 'arn:aws:states:us-west-1:121:stateMachine:test',
maxResults: '2',
nextToken: null,
statusFilter: 'SUCCEEDED'
};
var isSuccess
stepfunctions.listExecutions(params, function (err, data) {
if (err) console.log(err, err.stack);
else
data.executions.forEach(function (result) {
let params = {
executionArn: result.executionArn
};
stepfunctions.describeExecution(params, function (err, data) {
if (err) console.log(err, err.stack);
else {
isSuccess = 'true'
}
});
});
console.log('isSuccess: ' +isSuccess)
});
Expected output:
isSuccess: true
But I'm getting
isSuccess: undefined
Could you please help me to resolve this issue. Appreciated your help and support on this.
This is how you can wrap it on promise
let isSuccess;
const listExecute = function(params) {
return new Promise((resolve, reject) => {
stepfunctions.listExecutions(params, function (err, data) {
if (err) reject(err);
else
data.executions.forEach(function (result) {
let params = {
executionArn: result.executionArn
};
stepfunctions.describeExecution(params, function (err, data) {
if (err) reject(err);
else {
resolve(true)
}
});
});
});
})
}
async function getOutout(params) {
try {
isSuccess = await listExecute(params);
console.log(isSuccess, 'Output')
} catch(e) {
console.log(e)
}
}
getOutout(params)
Also you can export the listExecute so that you can use this function outside of this file.
module.exports = {listExecute}
I tried without success, to execute my Promise with Sequelize on stored procedure(MSSQL) inside the function, below the code (when I don´t use the Promise, this code runs perfectly, retrieving the json´s data):
function getData(numTravessia) {
return new Promise((resolve, reject) => {
return connection.query(
'EXEC [dbo].[SP_RECUPERAINFOTRAVESSIA] #ID=:param1',
{
replacements: {
param1: numTravessia,
},
type: QueryTypes.SELECT
},
(error, meta, body) => {
if (body != undefined) {
resolve(body.toString());
} else {
reject(error);
}
})
});
}
async function getInfoTravessia(numTravessia) {
try {
var r = await getData(numTravessia);
return JSON.parse(r);;
} catch (error) {
console.log(error);
}
}
app.listen(8000, () => {
console.log("aplicativo em execução");
getInfoTravessia(1955).then((result) => {
console.log(result);
}).catch((e) => {
console.log(e);
})
});
Below, follow the code snippet that I don´t use the Promise and it´s working:
connection.query(
'EXEC [dbo].[SP_RECUPERAINFOTRAVESSIA] #ID=:param1',
{
replacements: {
param1: 1955,
},
type: QueryTypes.SELECT
}).then((result) => {
// RETORNA UM STRING
var obj = result[0];
res.send(obj);
// return obj;
}).catch((e) => {
console.log('error', e);
});
Please, anyone can help me?
I'm writing a test for some code that will use Promise.race to bring back a result from a graphql service that is on (could be on) multiple servers. I've used Nock to mock the request, which works fine when I'm hitting a single service. When I mock up multiple services, Nock throws an error saying
AssertionError: expected [Function] to not throw an error but 'Error: Error: Nock: No match for request {\n "method": "POST",\n "url": "http://94.82.155.133:35204",\n "headers": {\n "content-type": "application/json",\n "accept": "application/json"\n },\n "body": "{...}"\n}' was thrown
my test looks like this:
it('should make two POST requests to the service for data from graphQL', async () => {
const spy = sinon.spy(releases, '_queryGraphQL');
const releaseID = 403615894;
nock.cleanAll();
const services = serviceDetails(NUMBER_OF_SERVICES); // NUMBER_OF_SERVICES = 3
nock(serviceDiscoveryHost)
.get('/v1/catalog/service/state51')
.reply(HTTP_CODES.OK, services);
for (const service of services) {
const currentNodeHealth = nodeHealth(service.Node);
nock(serviceDiscoveryHost)
.get('/v1/health/node/'+service.Node)
.reply(HTTP_CODES.OK, currentNodeHealth);
const delayTime = Math.floor(Math.random()*1000);
nock('http://'+service.Address+':'+service.ServicePort, serviceHeaders)
.post('/')
.delay(delayTime)
.replyWithError({code: 'ETIMEDOUT', connect: false})
.post('/')
.delay(delayTime)
.reply(HTTP_CODES.OK, getReply(releaseID))
}
const actual = await releases.getRelease(releaseID)
.catch((err) => {
console.log(releases._retries);
(() => { throw err; }).should.not.throw();
});
expect(releases._retries[releaseID]).to.be.equal(1);
expect(spy.callCount).to.be.equal(2);
expect(actual).to.be.an('object')
expect(actual.data.ReleaseFormatById.id).to.be.equal(releaseID);
});
and the offending bit of code looks like
async _queryGraphQL(releaseID, services) {
if (! this._retries[releaseID]) {
this._retries[releaseID] = 0;
}
const postData = this._getReleaseQuery(releaseID);
return Promise.race(services.map( (service) => {
const options = this._getHTTPRequestOptions(service);
return new Promise((resolve, reject) => {
let post = this.http.request(options, (res) => {
let data = '';
if (res.statusCode < 200 || res.statusCode > 299) {
const msg = this.SERVICE_NAME + ' returned a status code outside of acceptable range: ' + res.statusCode;
reject(new QueryError(msg, postData));
} else {
res.setEncoding('utf8');
res.on('data', (chunk) => {
data += chunk;
});
res.on('error', (err) => {
reject(new QueryError(err.message, postData, err));
});
res.on('end', () => {
resolve(JSON.parse(data));
});
}
});
post.on('error', async (err) => {
if (err.code === 'ETIMEDOUT') {
if (this._retries[releaseID] &&
this._retries[releaseID] === 3) {
reject(err);
} else {
this._retries[releaseID] += 1;
resolve(this._queryGraphQL(releaseID, services));
}
} else {
reject(new QueryError(err.message, postData, err));
}
});
post.write(JSON.stringify(postData));
post.end();
});
}));
}
this.http is just require('http');. and the options will be {hostname: service.hostname} \\ example.com etc.
What I'm expecting, is that if the first service to respond, responds with an error relating to: 'ETIMEDOUT', it'll recall the function (upto 2 more times) and try all the services again until the first service to respond is something that isn't a 'ETIMEDOUT'.
I have an Airtable base that I can retrieve records from (see code below), but I'd like to get the value for other fields besides just "Location". Using "console.log('Retrieved: ', record.get('Location'));", how do I modify this line to include in the output the field values for a field called "Size" in addition to the "Location" field? I tried "console.log('Retrieved: ', record.get('Location', 'Size'));", but that didn't work.
Here's an excerpt from my code:
// Lists 3 records in Bins
base('Bins').select({
// Selecting the first 3 records in Grid view:
maxRecords: 3,
view: "Grid view"
}).eachPage(function page(records, fetchNextPage) {
// This function (`page`) will get called for each page of records.
records.forEach(function(record) {
console.log('Retrieved: ', record.get('Location'));
});
// To fetch the next page of records, call `fetchNextPage`.
// If there are more records, `page` will get called again.
// If there are no more records, `done` will get called.
fetchNextPage();
}, function done(err) {
if (err) { console.error(err); return; }
});
OUTPUT
Retrieved 170000118
Retrieved 170000119
Retrieved 170000120
I found this repo to help in when I tried to product situations like this.
A wrapper for common functions for accessing data on an airtable.com database. All queries return promises.
Here is how it works if you want to avoid using an npm package. But ultimatly the jist of it is to either use request or some short of promise fulfillment menthod to retrive the Records.
import Airtable from 'airtable'
import _ from 'lodash'
const ENDPOINT_URL = 'https://api.airtable.com'
let API_KEY // Can only set the API key once per program
export default class AirTable {
constructor({apiKey, databaseRef}) {
if(!API_KEY) {
API_KEY = apiKey
Airtable.configure({
endpointUrl: ENDPOINT_URL,
apiKey: API_KEY
});
}
this.base = Airtable.base(databaseRef)
this.get = {
single: this.getSingleRecordFrom.bind(this),
all: this.getAllRecordsFrom.bind(this),
match: this.getAllMatchedRecordsFrom.bind(this),
select: this.getRecordsSelect.bind(this)
}
this.insert = this.createRecord.bind(this)
this.add = this.insert
this.create = this.insert
this.update = this.updateRecord.bind(this)
this.set = this.update
this.remove = this.deleteRecord.bind(this)
this.delete = this.remove
this.destroy = this.remove
this.rem = this.remove
}
async createRecord({tableName, data}) {
return new Promise((resolve, reject) => {
this.base(tableName).create(data, (err, record) => {
if (err) {
console.error(err)
reject()
return
}
console.log("Created " + record.getId())
resolve(record)
})
})
}
async updateRecord({tableName, id, data}) {
return new Promise((resolve, reject) => {
this.base(tableName).update(id, data, (err, record) => {
if (err) {
console.error(err)
reject()
return
}
console.log("Updated " + record.getId())
resolve(record)
})
})
}
async deleteRecord({tableName, id, data}) {
return new Promise((resolve, reject) => {
this.base(tableName).destroy(id, (err, record) => {
if (err) {
console.error(err)
reject()
return
}
console.log("Deleted " + record.getId())
resolve(record)
})
})
}
async getSingleRecordFrom({tableName, id}) {
console.log(tableName, id)
return new Promise((resolve, reject) => {
this.base(tableName).find(id, function(err, record) {
if (err) {
console.error(err)
reject(err)
}
resolve(record)
})
// console.log(record);
})
}
async getAllRecordsFrom(tableName) {
return this.getRecordsSelect({tableName, select: {} })
}
async getAllMatchedRecordsFrom({tableName, column, value}) {
return this.getRecordsSelect({tableName, select: {filterByFormula:`${column} = ${value}`} }) // TODO: validate input
}
async getRecordsSelect({tableName, select}) {
return new Promise((resolve, reject) => {
let out = []
this.base(tableName).select(select).eachPage((records, fetchNextPage) => {
// Flatten single entry arrays, need to remove this hacky shit.
_.map(records, r => {
_.forOwn(r.fields, (value, key) => { // If array is single
if(_.isArray(value) && value.length == 1 && key != 'rooms') {
r.fields[key] = value[0]
}
});
})
out = _.concat(out, records)
fetchNextPage();
}, (err) => {
if (err) {
console.error(err)
reject(err)
} else {
// console.log(JSON.stringify(out, null, 4))
// console.log("HI")
resolve(out)
}
})
})
}
}
Hope this Makes sense, Also trying to make an API-Proxy fetching a whole table or even use Express to fetch record id's as arrays can work as well
You can use this code line.
records.forEach(function(record) {
console.log('Retrieved: ', record.get('Location') + ' ' + record.get('Size'));
});
There is a code. It's logic is at first to get file from a client (uploadFile), then load it to another server (changeImage), then load the answer (loadFile). It's all done with promises to chain them together but it doesn't work. It keeps to fall dawn. I have tried to change it a lot. Well actually I spent this whole day trying. But there is no result. In this version it's falling without any mistakes in console. Can you help me?
<pre>
var fs = require('fs'),
http = require('http'),
url = require('url'),
multiparty = require('multiparty'),
request = require('request');
var server = new http.Server();
var ifs = require('os').networkInterfaces();
var result = Object.keys(ifs)
.map(x => [x, ifs[x].filter(x => x.family === 'IPv4')[0]])
.filter(x => x[1])
.map(x => x[1].address)[2];
console.log('\nUse this ip: ' + result);
console.log("Successfully started\n");
server.listen('80', result);
server.on('request', onRequest);
function onRequest(req, res) {
var parsed = url.parse(req.url, true);
switch (parsed.pathname) {
case '/':
case '/index.html':
fs.readFile('index.html', function(err, file) {
if (err) res.end();
res.end(file);
});
break;
case '/file':
uploadFile(req)
.then(function(a) {
return changeImage({
'uploadfile': fs.createReadStream('./files/temp.jpg'),
'ef-set': 10,
'ef-set-2': 10,
'jpeg-quality': 80
}, 'https://www.imgonline.com.ua/grid-square-result.php',
'http://www.imgonline.com.ua/',
new RegExp(/download\.php\?file=.+?\.jpg/))
})
.then(function(link) {
//it falls before here because console.log('H') here won't show 'H' :-|
loadFile(link);
})
.then(function() {
return changeImage({
'uploadfile': fs.createReadStream('./files/temp.jpg'),
'efset1': 2,
'outformat': 2,
'jpegtype': 1,
'jpegqual': 85,
'jpegmeta': 1
},
'https://www.imgonline.com.ua/add-effect-black-white-result.php', '',
new RegExp(/https:\/\/.+?\.jpg/)
);
})
.then(function(link) {
loadFile(link);
})
.then(function() {
res.end('files/temp.jpg');
})
.catch(function(err) {
console.log('ERR ', err);
});
break;
default:
fs.readFile('./' + req.url, function(err, file) {
if (err) res.end();
res.end(file);
});
}
}
function uploadFile(req) {
if (fs.existsSync('./files/temp.jpg')) {
fs.unlink('./files/temp.jpg', function(err) {
if (err) reject(err);
});
}
return new Promise(function(resolve, reject) {
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
var path = files.uploadfile[0].path;
fs.copyFile(path, './files/temp.jpg', function(err) {
if (err) reject('ERRinCOPYING');
fs.unlink(path, function(err) {
if (err) reject(err);
var a = 0;
var timer = setInterval(function() {
if (fs.existsSync('./files/temp.jpg')) {
clearInterval(timer);
resolve();
}
}, 10);
});
});
});
});
}
function changeImage(formData, url, link, regExp) {
return new Promise(function(resolve, reject) {
request.post({
url: url,
formData: formData
}, function(err, resp, body) {
if (err) reject('ERRinREQUEST: ' + err);
link += body.match(regExp);
if (link.length > 32) {
resolve(link);
} else {
reject('ERROR! LINK WAS NOT FOUND');
}
});
});
}
function loadFile(link) {
request
.get(link)
.on('response', function(response) {
response.pipe(fs.createWriteStream('./files/temp.jpg'));
});
}
</pre>
The thing is if I comment the uploadFile() and run the rest of the script then everything works fine, and the opposite if I comment the rest of the script and leave only uploadFile() uncommented then again everything works.
Console shows nothing. Just on the client side I see the rejection of the connection. But nothing in the console. If I put console.log() right in 'return new Promise()' in changeImage it will show nothing
UPD: I ran the script with "node server" not as usual with "supervisor server" and it started to work without failings. But why? :\
You are likely running into a file system permission issue. When you run the script via node server as you mention, the process does not have the permission, which you do have when executing via supervisor server.