Specific example from kubernetes-client:
Application code:
console.log(`Trying to create a namespace: ${namespaceName}`)
try {
await client.api.v1.namespaces(namespaceName).get()
} catch (err) {
try {
await client.api.v1.namespaces.post(namespaceJson)
} catch (err) {
console.log('Error creating namespace: ' + err)
return new Promise(function (resolve, reject) {
reject(new Error(`Failure creating namespace: ${namespaceName}: ${err}`))
})
}
...
Tests:
jest.doMock('kubernetes-client', () => {
const aRejection = jest.fn(() => {
const err = new Error(404)
err.response = 'Not found'
err.status = 404
err.statusCode = 404
return Promise.reject(err)
})
const aPromise = jest.fn(() => {
return Promise.resolve({
body: {
data: {
username: 'dXNlcm5hbWUK' // 'username', base64-encoded
}
}
})
})
const namespaces = jest.fn().mockReturnValue({
get: aRejection,
post: aPromise
})
const mockClient = {
api: {
v1: {
namespaces
}
},
}
return {
Client: jest.fn(() => mockClient),
}
})
Note that client.api.v1.namespaces.post(namespaceJson) (namespaces is an object) and client.api.v1.namespaces(namespace).get() (namespaces is a function) are both valid.
If I mock namespaces as a function, the tests fail because client.api.v1.namespaces.post() is not a function.
Hopefully I'm just doing something wrong somewhere but I don't know what that is.
Related
I don't know where II am missing something in the code as It's working clearly from postman.
my backend Nodejs server function is :
exports.updateFCMToken = (req, res) => {
try {
User.findByIdAndUpdate(
req.params.id,
{
$set: {
fcmToken: req.body.fcmToken
}
},
(err, doc) => {
if (err) {
console.log(err);
res.status(400).send('update FCMToken - Error')
}
return res.status(200).send('FCMToken Updated Successfully')
}
)
}
catch (err) {
console.log(err);
res.status(400).send('server Error - FCMToken')
}
}
From component I am calling the action:
useEffect(() => {
setTimeout(async () => {
dispatch(updateFCMTokenAction());
}, 1000);
}, [])
my action.js: (doc id and fcmtoken are not similar to output shown in code)
export const updateFCMTokenAction = () => {
return async (dispatch) => {
try {
dispatch({ type: userConstants.UPDATE_FCMTOKEN_REQUEST });
getToken();
const fcmToken = await AsyncStorage.getItem('fcmToken');
const user = await AsyncStorage.getItem('user');
const pushToken = {fcmToken};
const id = JSON.parse(user)._id; // output: 63806e0f4dzeb09a2c03f731
console.log('-----------------updateFCMTokenAction--------------');
console.log('updateFCMTokenAction-fcmToken:', pushToken); // output: {"fcmToken": "fv4-4GIWTymgrt7e3klaPs:APA91bGXOLTNfp4-j4dPVDEL-6lDVUA7GWZchwx4j2BlVPOvOsq3pDOk06xkfBE-Q-J6Q4zix8LX-Jf-69Ey2T22aYmbiVD4j4_kMbVlZa8ip1MRtQ-ZDs0hMpno53o7BjmB9Opc-LWR"}
const res = await axiosInstance.post(`/updatefcmtoken/${id}`, pushToken);
console.log('res: ', res);
dispatch({ type: userConstants.UPDATE_FCMTOKEN_SUCCESS, payload: res.data });
} catch (err) {
console.log('push-err: ', err)
dispatch({ type: userConstants.UPDATE_FCMTOKEN_FAILURE, payload: err });
}
}
}
I am getting an error as :
push-err: [AxiosError: Request failed with status code 400]
What am I missing/unable to see here ?
Thank You ,
Firstly, To be fair, I am neither a developer nor a reactjs or node expert. I love the functional programming and async nature that has drawn me to the javascript world. I am more of a pythonic person.
I have a firebase callable function . I can print the nested value with console.log but however have failed to return the value back to my react-redux app.
I strongly feel I am not using promises correctly. I am treating the promises to somehow return the values but am able to only do console.log on the value i want but fail to return it from firebase callable function
I have created the firebase callable function as following. Redux action invokes the firebase callable function. I get
// firebase callable function
const functions = require('firebase-functions');
const cors = require('cors')({origin: true});
const dns = require('dns');
const util = require('util')
const getIP = function(domain) {
return new Promise((resolve, reject) => {
dns.lookup(domain, (err, res) => {
if(err) {
reject(err)
}
if (res) {
resolve(JSON.stringify(res))
}
})
})
}
exports.getIP = functions.https.onCall((data, context) => {
return {
addresses: getIP(data.domain).then((res) => {
console.log(res)
return res
}).catch((err) => {
console.log(err)
})
}
})
// react-redux store action
export const getIPAddress = (domain) => {
return (dispatch, getState, {getFirebase}) => {
const firebase = getFirebase();
var dr = firebase.functions()
dr({
domain: domain
}).then((result) => {
console.log("check", result)
dispatch({ type: 'IPADDRESS_SUCCESS', result: result});
}).catch((err) => {
dispatch({ type: 'IPADDRESS_ERROR', err: err });
})
}
}
Expected output: ['ipaddress1', 'ipaddress2']
Current output: object
data:
addresses:
domain: {domain: null, _events: {…}, _eventsCount: 1, _maxListeners: null, members: Array(0)}
__proto__: Object
__proto__: Object
__proto__: Object
type: "IPADDRESS_SUCCESS"
__proto__: Object
Try this:
const functions = require('firebase-functions');
const cors = require('cors')({origin: true});
const dns = require('dns');
const util = require('util')
const getIP = function(domain) {
return new Promise((resolve, reject) => {
dns.lookup(domain, (err, res) => {
if(err) {
reject(err)
}
if (res) {
resolve(res)
}
})
})
}
exports.getIP = functions.https.onCall(async (data, context) => {
try {
return {
addresses: await getIP(data.domain)
};
} catch (err) {
console.log(err);
}
})
I have a typescript module.
public multipleQuery(queries: string[]) {
return new Promise(async (resolve, reject) => {
const cPool = new sql.ConnectionPool(this.room.db);
await cPool.connect().then((pool: any) => {
const transaction = new sql.Transaction(pool);
return transaction.begin(async (err: any) => {
const request = new sql.Request(transaction, { stream: true });
try {
queries.forEach(async (q) => {
await request.query(q);
});
transaction.commit((err2: any) => {
pool.close();
if (err2) {
reject(err2);
} else {
resolve(true);
}
});
} catch (err) {
transaction.rollback(() => {
pool.close();
reject(err);
});
}
});
}).catch((err: Error) => {
cPool.close();
reject(err);
});
});
}
queries variable is an array of string, I put inside a lot of sql insert queries.
No matter what I write in queries, I still receive this error, why?
RequestError: Requests can only be made in the LoggedIn state, not the
SentClientRequest state TransactionError: Can't acquire connection for
the request. There is another request in progress.
the solutions is to use async
const async = require("async");
public multipleQuery(queries: string[]) {
return new Promise((resolve, reject) => {
const pool = new sql.ConnectionPool(this.room.db);
return pool.connect().then((p: any) => {
const transaction = new sql.Transaction(p);
return transaction.begin((err: any) => {
const request = new sql.Request(transaction);
if (err) {
reject(err);
}
return async.eachSeries(queries, async (query: any, callback: any) => {
return request.query(query);
}, async (err2: any) => {
if ( err2 ) {
await transaction.rollback(() => {
pool.close();
reject(err2);
});
} else {
await transaction.commit(() => {
pool.close();
resolve(true);
});
}
});
});
});
});
}
I am trying to use the updateIntent function that is part of the Dialogflow v2 Client library for Node.js . The reason I am trying to use it, is to be able to add training phrases to an intent.
I cannot seem to get passed this one. Here is the code I am using for it!:
My GetIntent Function:
async function getIntent(intentId) {
try {
let responses = await intentsClient.getIntent({name: intentId, intentView: 'INTENT_VIEW_FULL'})
const response = responses[0]
// console.log(response)
return new Promise((resolve, reject) => {
resolve(response)
})
} catch (err) {
return new Promise((resolve, reject) => {
reject(err)
})
}
}
My UpdateIntent Function:
async function updateIntent(intent) {
const request = {
intent: intent,
languageCode: 'en-US',
updateMask: {
paths: ['trainingPhrases']
},
intentView: 'INTENT_VIEW_FULL'
}
try {
let responses = await intentsClient.updateIntent(request)
return new Promise((resolve, reject) => {
resolve(response)
})
} catch (err) {
console.log(err)
return new Promise((resolve, reject) => {
reject(err)
})
}
}
The Function that Calls it:
async function testUpdateTraining () {
try {
let intent = await getIntent('projects/small-talk-1-406ae/agent/intents/ac7f0b68-de5c-4b6f-9393-358dd2b0c1bd')
let trainingPhrase = { parts: [{ text: 'How should I behave on the trails?'}],
type: 'EXAMPLE'}
intent.trainingPhrases.push(trainingPhrase)
try {
let updatedIntent = await updateIntent(intent)
} catch (e) {
console.log(e)
console.log('failed to update the intent')
}
} catch (err) {
console.log('failed to get intent')
}
}
Now the weird thing is - I am getting a 200 response from the client library call. The Api doc states that upon a successful response you will get an intent object. I am getting an intent object with the training phrases inside...
[![{ inputContextNames: \[\],
events: \[\],
trainingPhrases:
\[ { parts: \[Array\],
name: 'ad0d1f6a-78cf-4e0b-84ca-ec62a45c75dc',
type: 'EXAMPLE',
timesAddedCount: 0 },
{ parts: \[Array\],
name: 'e33cce4b-96ee-4e35-a151-5b09ff603817',
type: 'EXAMPLE',
timesAddedCount: 0 },
{ parts: \[Array\],
name: '7d9b7c56-5fa8-4791-986f-e57b9f90d431',
type: 'EXAMPLE',
timesAddedCount: 0 } \],
outputContexts: \[\],
parameters: \[\],
messages:
\[ { platform: 'PLATFORM_UNSPECIFIED',
text: \[Object\],
message: 'text' } \],
defaultResponsePlatforms: \[\],
followupIntentInfo: \[\],
name: 'projects/small-talk-1-406ae/agent/intents/ac7f0b68-de5c-4b6f-9393-358dd2b0c1bd',
displayName: 'faq.offroad.card1answer',
priority: 500000,
isFallback: false,
webhookState: 'WEBHOOK_STATE_UNSPECIFIED',
action: 'faq.offroad.card1answer',
resetContexts: false,
rootFollowupIntentName: '',
parentFollowupIntentName: '',
mlDisabled: true }][1]][1]
This is what dialogflow has. Only two training phrases here, the one I added programmatically does not show up.
So my question is, how can I format the request so I can update the training phrases without a problem? Is there an example I can run off?
After trying out a lot, understood that my code worked because i removed update mask. And the languageCode as well, because it was giving me an error.
The code is as below and works fine.
Check it up.
This is the getIntent function:
async function getIntent(intentId) {
try {
let responses = await intentsClient.getIntent({
name: intentId,
intentView: 'INTENT_VIEW_FULL'
})
const response = responses[0];
console.log(util.inspect(response, false, null, true /* enable colors */ ));
return new Promise((resolve, reject) => {
resolve(response)
})
} catch (err) {
return new Promise((resolve, reject) => {
reject(err)
})
}
}
The function that calls it:
async function testUpdateTraining () {
try {
let intent = await getIntent('<your_ID>')
let trainingPhrase = {
parts: [{
text: 'let me call you?'
}],
type: 'EXAMPLE'
}
intent.trainingPhrases.push(trainingPhrase)
try {
let updatedIntent = await updateIntent(intent)
} catch (e) {
console.log(e)
console.log('failed to update the intent')
}
} catch (err) {
console.log('failed to get intent')
}
}
The UpdateIntent function:
async function updateIntent(intent) {
const request = {
intent: intent,
intentView: 'INTENT_VIEW_FULL'
}
try {
let responses = await intentsClient.updateIntent(request)
return new Promise((resolve, reject) => {
resolve(responses)
})
} catch (err) {
console.log(err)
return new Promise((resolve, reject) => {
reject(err)
})
}
}
You can try:
updateMask: {
paths: ['training_phrases']
}
since paths naming convetion is "snake"
Been hunting the internet trying to find an answer to why the following doesn't work.
I am trying to pass in the req object when I add the job so that I have access to it when the job is processed.
But the process is never executed when the whole req object is passed to job.data. Yet I can pass parts of the req object.
What I'm trying to do maybe anti-pattern and a big no no. But, I am trying to understand why it won't work. It seems strange that it just continues without any error.
Below is an example, hopefully it is clear.
My kue is abstracted into a separate file, and initialised onto app.locals.Q as follows:
// Q.js
class Q {
constructor(options) {
this.q = kue.createQueue(options)
}
addJob = (name, data) => {
return Queue.create({
queue_job: name,
queue_route: data.route,
queue_user: data.user,
queue_added: new Date(),
})
.then(response => {
this.q.create(name, {
id: response.get('queue_id'),
route: data.route,
request: data.request
})
.save();
return Promise.resolve(response);
})
.catch(error => {
return Promise.reject(error);
});
processJob = (name, work, options = {}) => {
const {concurrency} = options;
this.q.process(name, concurrency || 1, (job, done) => {
const {data: {id, route, request}} = job;
Queue.update({
queue_running: true
}, {
where: {
queue_id: id
}
})
.then(() => {
if (process.env.NODE_ENV !== 'production') {
console.log(`running job ${id} from ${route}`);
}
return new Promise((resolve, reject) => {
return work(resolve, reject, request);
});
})
.then(results => {
return Queue.update({
queue_running: false,
queue_completed: new Date(),
queue_results_path: results || null
}, {
where: {
queue_id: job.data.id
}
});
})
.then(() => {
if (process.env.NODE_ENV !== 'production') {
console.log(`completed job ${id} from ${route}`);
}
done();
})
.catch((error) => {
if (process.env.NODE_ENV !== 'production') {
console.log(`failed job ${id} from ${route}`);
console.log(error);
}
Queue.update({
queue_running: false,
queue_error: `${error}`
}, {
where: {
queue_id: id
}
})
.then(() => {
done(error);
})
.catch(err => {
console.error(err);
done(err);
});
});
});
};
};
// example route
queue = (req, res) => {
const {locals: {Q}} = req.app;
Q.addJob('foo', {
route: req.path,
user: req.user.get('username'),
request: req
})
.then(queue_id => {
Q.processJob('foo', (resolve, reject, request) => {
console.log(request)
resolve('complete')
})
res.json({sucess: true})
})
}
redis can't serialize the req object.
kue simply silently fails.