How to use image4io on node js - node.js

Im having problem following the documentation on image4io.
I just tried stuff. So the problem is that the image4io only returns Promise {}
here is my code
module.exports = function(app,db){
const Image4ioAPI = require('#image4io/image4ionodejssdk');
app.post('/addImage',(req,res)=>{
var apiKey = 'api key';
var apiSecret = 'api secret';
var api = new Image4ioAPI.Image4ioClient(apiKey, apiSecret);
let response=api.GetSubscription();
console.log(response)
})
}

It returns a promise you must use then or catch to access the response after the promise is fulfilled.
Ideal use case:
api.GetSubscription()
.then(response => {
// Response returns a JSON object, which can be accessed here
}).catch(error => {
throw error;
})

You can await a promise to show its result.
module.exports = function(app,db){
const Image4ioAPI = require('#image4io/image4ionodejssdk');
app.post('/addImage', async (req,res)=>{
var apiKey = 'api key';
var apiSecret = 'api secret';
var api = new Image4ioAPI.Image4ioClient(apiKey, apiSecret);
let response= await api.GetSubscription();
console.log(response)
})
}

Related

Node.js requests and cheerio output blank

I'm learning scraping using node.js requests and cheerio. I write a simple code to display title from a web page.
My code :
const request = require("request");
const cheerio = require("cheerio");
const url = "https://singapore.craigslist.org/d/automotive-services/search/aos"
async function scrapeCraigslist() {
try {
const htmResult = await request.get(url);
const $ = await cheerio.load(htmResult);
$(".result-info").each((index, element) => {
const title = $(element)
.children(".result-title")
.text();
console.log(title);
console.log("sk");
});
} catch (err) {
console.error(err);
}
}
scrapeCraigslist();
But when i run the code i'm getting blank nothing errors and no ouput.
Output :
Microsoft Windows [Version 10.0.18362.720]
(c) 2019 Microsoft Corporation. All rights reserved.
C:\Users\Ahmed-PC\craigslist>node index.js
C:\Users\Ahmed-PC\craigslist>
My selection and result is coming in Chrome Developer Tools console. but not coming in node.js code
You're using request with a promise style interface, if you wish to do this you'll need to use request-promise (or you could use Axios, node-fetch etc.).
If you use request-promise your code should work fine:
request-promise
const request = require("request");
const cheerio = require("cheerio");
const rp = require("request-promise");
const url = "https://singapore.craigslist.org/d/automotive-services/search/aos"
async function scrapeCraigslist() {
try {
const htmResult = await rp.get(url);
const $ = await cheerio.load(htmResult);
$(".result-info").each((index, element) => {
const title = $(element)
.children(".result-title")
.text();
console.log(title);
console.log("sk");
});
} catch (err) {
console.error(err);
}
}
scrapeCraigslist();
request (with callback)
const request = require("request");
const cheerio = require("cheerio");
const url = "https://singapore.craigslist.org/d/automotive-services/search/aos"
async function scrapeCraigslist() {
request.get(url, async (error, response, htmResult) => {
if (error) {
// Something went wrong
console.error(error);
} else {
// The request was successful
const $ = await cheerio.load(htmResult);
$(".result-info").each((index, element) => {
const title = $(element)
.children(".result-title")
.text();
console.log(title);
console.log("sk");
});
}
});
}
scrapeCraigslist();

Sinon stub not working if tested using express app

I have a a controller function like below.
SendOTPController.js
const otpService = require('../services/otpService')
module.exports = async function(req, res) {
const {error, data} = await sendOTP(req.query.phone)
if(error)
return res.send(error)
return res.send(data)
}
otpService.js
module.exports = async function(phone) {
await result = fetch(`http://api.send-otp?phone=${phone}`)
if (result !== sucess)
return {
error: "Failed to send OTP!"
data: null
}
return {
error: null
data: result
}
}
Below is my test.
const expect = require('chai').expect
const request = require('supertest')
const sinon = require('sinon')
const rewire = require('rewire')
const SendOTPController= rewire('../../src/controllers/SendOTPController')
const app = require('../../src/app')
describe('GET /api/v1/auth/otp/generate', function () {
it('should generate OTP', async () => {
let stub = sinon.stub().returns({
error: null,
data: "OTP sent"
})
SendOTPController.__set__('sendOTPOnPhone', stub)
const result = await request(app)
.get('/api/v1/auth/otp/generate?phone=8576863491')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200)
console.log(result.body)
expect(stub.called).to.be.true
})
})
In above code the stub is not being called.
But if use only controller without using express app it works fine.
const expect = require('chai').expect
const request = require('supertest')
const sinon = require('sinon')
const rewire = require('rewire')
const SendOTPController= rewire('../../src/controllers/SendOTPController')
const app = require('../../src/app')
describe('GET /api/v1/auth/otp/generate', function () {
it('should generate OTP', async () => {
let stub = sinon.stub().returns({
error: null,
data: "OTP sent"
})
SendOTPController.__set__('sendOTPOnPhone', stub)
const result = await SendOTPController() // not using express app, hence not passing req, res
console.log(result)
expect(stub.called).to.be.true
})
})
I went through many modules and docs.
They give a solution how I can stub a module.exports = async function(){}.
They also work, but only If they are directly imported and tested.
They don't work if I use it with express app.
Any help would be appreciated, thanks.
Instead of returns try to use resolves:
let stub = sinon.stub().resolves({
error: null,
data: "OTP sent"
})
returns is for sync code, resolves for async.

How to deal with the different type of errors that returns from the cloud function?

I have written the cloud functions which sends the response either with the statuscode 200 or 400 but sometimes I am getting this error
Function execution took 219 ms, finished with status: 'connection error'
Error: function crashed out of request scope Function invocation was interrupted.
So the problem is I need to know send this error message with some statuscode as the response of the cloud function.
const functions = require('firebase-functions');
const dialogflow = require('dialogflow');
const admin = require('firebase-admin');
const Firestore = require('#google-cloud/firestore');
const firestore = new Firestore();
admin.initializeApp();
var db = admin.firestore();
const {WebhookClient} = require('dialogflow-fulfillment');
var UID = new Object();
exports.fulfillmenttext = functions.https.onRequest((req,res) =>{
const answer1 = req.body.Text;
const uid = answer1.substring(0,28);
const answer = answer1.substring(28);
const sessionId = uid;
var count,questvalue;
const promise = db.collection("***").doc('***').collection("**").doc("uid").get();
promise.then(doc => {
snapshot.forEach(function(doc) {
if (doc.exists) {
count = doc.data().count;
if(count == 1){
var updatequest = title[questvalue];
res.status(200).send({"question":updatequest,"question_number":questvalue});
return;
}
else{
runSample();
}
}
else {
console.log("No such document!");
}
});
}).catch(function(error) {
console.log("Error getting document:", error);
});
async function runSample() {
const languageCode = 'en-US';
const projectId = 'xxxxxxx';
const credentials = {
client_email: 'xxxxxxx',
private_key:
'xxxxxxx',
};
//Instantiate a DialogFlow client.
const dialogflow = require('dialogflow');
const sessionClient = new dialogflow.SessionsClient({
projectId,
credentials,
});
// Define session path
const sessionPath = sessionClient.sessionPath(projectId, sessionId);
// The text query request.
const request = {
//session: context1,
session: sessionPath,
queryInput: {
text: {
text: answer,
languageCode,
},
},
};
const responses = await sessionClient.detectIntent(request);
const result = responses[0].queryResult;
let action = result.action;
if (result.intent) {
const question = result.fulfillmentText;
console.log("question is",question);
const actionHandlers = {
'early': () => {
console.log('earlyaction1', action);
let name1 = JSON.stringify(result.parameters.fields.Name.stringValue);
name1 = name1.toString().replace(/"/g,"");
var data1 = {
Name: name1
};
var setDoc1 = admin.firestore().collection('**').doc('uid').collection("***").doc('uid').collection('**').doc('**').update(data1);
},
};
if (action === 'early') {
console.log('1');
actionHandlers[action]();
}
res.status(200).send({"question":result.fulfillmentText,"action":action,"question_number":title.indexOf(question)});
} else {
console.log(` No intent matched.`);
res.status(400).send({"action":"empty"});
}
}
});
That message is telling you that you have some async code that was still running after the function terminated normally by sending a response to the client. That bit of async code crashed. Since the function already terminated by sending a response, there's nothing you can do to send another response. There can only be one response per function invocation.
What you'll have to do is review your code and make sure you're 1) handling promises correctly and 2) not intentionally trying to leave any work going after sending the response, since Cloud Functions does not support that.

Why bodyParser returns undefined?

I can't get body of request for the POST http://127.0.0.1:3001/users?name=Slava.
Server responce 'name is required'. Method getUsers work correctly. RethinkDB works good, server.js works too. I searched for similar answers here, but there is nothing suitable. There are very old answers, but they are not relevant.
This is request: http://127.0.0.1:3001/users?name=bob (I use Postman for POST)
Why bodyParser don't work in my code? I have no idea why this happens.
const Koa = require('koa')
const logger = require('koa-morgan')
const bodyParser = require('koa-bodyparser')
const Router = require('koa-router')
const r = require('rethinkdb')
const server = new Koa()
const router = new Router()
const db = async() => {
const connection = await r.connect({
host: 'localhost',
port: '28015',
db: 'getteamDB'
})
return connection;
}
server.use(bodyParser());
const insertUser = async(ctx, next) => {
await next()
// Get the db connection.
const connection = await db()
// Throw the error if the table does not exist.
var exists = await r.tableList().contains('users').run(connection)
if (exists === false) {
ctx.throw(500, 'users table does not exist')
}
let body = ctx.request.body || {}
console.log(body);
// Throw the error if no name.
if (body.name === undefined) {
ctx.throw(400, 'name is required')
}
// Throw the error if no email.
if (body.email === undefined) {
ctx.throw(400, 'email is required')
}
let document = {
name: body.name,
email: body.email
}
var result = await r.table('users')
.insert(document, {returnChanges: true})
.run(connection)
ctx.body = result
}
router
.post('/users', insertUser)
server
.use(router.routes())
.use(router.allowedMethods())
.use(logger('tiny')).listen(3001)
Body parser is used to parse POST requests (for POST body), here you have to use req.query instead of req.body, follow up this question.

Koa.js always get Not Found 404

I develop in Koa and I use Firebase to messaging, because of a real-time database. When I want to get messages from firebase I get Not found, but in console.log() it shows me.
This is my function to getConversation(Messages)
async getConversation(conversationName, callback) {
var ref = await admin.database().ref(`messages/${conversationName}`)
await ref.on('value', (snapshot, prevChildKey) => {
var newPost = snapshot.val()
let values = Object.values(newPost)
callback(values)
})
}
Then I call it in another controller like this
async getMessages(ctx) {
const id = ctx.params.id
const nameOfConversation = await ctx.db.Conversation.findById(id)
await firebaseIndex.fbController.getConversation(nameOfConversation.name, response => {
console.log(response)
ctx.body = response //TODO
})
}
At the last, I call it in routes.
router.get('/getConversation/:id', middlewares.isAuthenticate, controllers.userConversation.getMessages)
I always get body Not found.
Do anybody know how I can solve it?
I solved it.
async getMessages(ctx) {
const id = ctx.params.id
const nameOfConversation = await ctx.db.Conversation.findById(id)
ctx.body = await new Promise((resolve, reject) => {
firebaseIndex.fbController.getConversation(nameOfConversation.name, async response => {
resolve(response)
})
})
}
ctx.body has to have a Promise.

Resources