How to display Axios' Then response after form validation with VueJS 3 - axios

I'm having a problem that I can't solve.
This is my problem, I have a validated form that returns a sending confirmation response.
I get the message in question in the console, but no way to display it on the page.
If any good soul could tell me where the error is and how to fix it, that would be great...
Here is the code in question
function onSubmit(values) {
const validationformulaire = “”;
axios
.post(‘http://adresse_d_envoi’, values)
.then((response) => {
return axios
.get(‘http://adresse_de_retour’)
// .then((response) => (this.validationformulaire = response.data.test))
.then(response =>
console.log(response.data.validationformulaire),
console.log(validationformulaire))
.catch(error => console.log(error))
});
}
I have already tried many attempts without result.
Yet I see the response in the console, so I retrieve the response well but I can't get it out of the function and display it.

Related

Axios Delete Not Working In React App But Working In PostMan/Insomnia

Axios DELETE works when I send a request through postman but on my react app it doesn't. I'm passing the _id that MongoDB assigns the entry. I'm initiating ObjectId and it still doesn't work. I also double checked if I was using the correct route, which I was.
In my app I have click function that calls SaveBook. That part I feel okay about. Let me know if I need to share something else.
SaveBook in AuthActions.js on the front end
export const saveBook = ({books, user, book, _id}) => {
return function () {
console.log(`This is id ${JSON.stringify(_id)}`)
const savedIndex = books.indexOf(book);
if (savedIndex >= 0) {
console.log(savedIndex)
axios
.delete("/api/users/wishlist", {_id})
} else {
console.log(savedIndex)
// console.log(`Adding ${book.book.title} to faves...`);
axios
.post("/api/users/dashboard", {book, user})
.then(console.log("success"))
.catch (err =>
json(err)
);
}
}
};
In users.js the delete operation on the server side
router.delete('/wishlist', (req, res) => {
const db = mongoUtil.getDb();
db.db("mern-auth-2").collection("savedbooks")
.deleteOne({_id:ObjectId(req.body._id)})
.then(res.json(res.data))
});
I realized req.body wasn't the correct choice for the Delete method and used url params/ req.params to send the _id. This works well.
Fixed this line in authActions.js
axios
.delete("/api/users/wishlist/" + _id,)
Fixed these few lines in Users.js
router.delete('/wishlist/:id', (req, res) => {
const db = mongoUtil.getDb();
db.db("mern-auth-2").collection("savedbooks")
// .deleteOne({_id:ObjectId(req.body._id)})
.deleteOne({_id:ObjectId(req.params.id)})

How to display API data using fetch on Dialogflow GUI

I want to display data from OMDB API on Dialogflow GUI but it's not happening. Data is being displayed fine on Google Cloud Console.
function infoHandler(agent){
let movieName = agent.parameters.movie;
agent.add(`The information for ${movieName} is as follow`);
fetch('http://www.omdbapi.com/?apikey=e255decd%20&s='+ movieName)
.then(result => result.json())
.then((json) => {
let id = json.Search[0].imdbID;
fetch('http://www.omdbapi.com/?apikey=e255decd%20&i=' + id)
.then(result => result.json())
.then((json) => {
agent.add(json.Title + json.Plot + json.imdbRatinng);
return;
}).catch((ex) => {
console.log(ex);
});
})
.catch((e) => {console.log(e);});
The issue is that fetch() causes an asynchronous operation. However, there is nothing that indicates to the Dialogflow handler dispatcher that it is asynchronous and that it should wait for it to complete before sending back a reply. To do that, you'd need to return a Promise.
Fortunately the then/catch chain that you have that are built off the fetch() return a Promise. So all you need to do is return the Promise that they have. This is as simple, in your case, by placing a return before the fetch() call. So it would look something like this:
return fetch('http://www.omdbapi.com/?apikey=e255decd%20&s='+ movieName)
// Other lines remain the same

Intent not moving to next intent

first intent
second intent
As shown in the below code, the flow is not going from Number Intent to First Intent, it is been looped into the number loop. In dialog flow, with every intent corresponding context is also made. The flow is not moving as per context and is stuck in NumberIntent.
The flow should be like the google ask the user its survey id, the user says its id 612020 and google start asking its questions. The flow works fine until the type of question is rating i.e. user has to speak number. The error arises when the user is asked to answer in descriptive manner.
'use strict';
// Import the Dialogflow module from the Actions on Google client library.
const {dialogflow} = require('actions-on-google');
const functions = require('firebase-functions');
// Instantiate the Dialogflow client.
const app = dialogflow({debug: true});
const axios = require('axios').default;
global.ques = [];
global.i=0;
app.intent('Default Welcome Intent', (conv) => {
conv.add('Hello! What is your survey id?');
});
app.intent('NumberIntent', (conv,{number}) => {
return axios.get('https://www.openeyessurvey.com/api/get_open_survey_info/612020')
.then((result) => {
result.data.Item.QUESTIONS.map(questionobj => {
ques.push(questionobj.question);
})
conv.ask(ques[i]);
i+=1;
}).catch( err => {
console.log("error", JSON.stringify(err,null,2));
conv.close('This is not a valid survey ID');
});
});
app.intent('FirstIntent', (conv, {number}) => {
conv.ask(ques[i]);
i+=1;
});
app.intent('SecondIntent', (conv) => {
const des = conv.parameters.any;
if(des === 'ankit'){
conv.ask(ques[i]);
i+=1;
}
});
app.intent('ThirdIntent', (conv) => {
conv.ask(ques[i]);
i+=1;
});
app.intent('FourthIntent', (conv, {number}) => {
conv.ask(ques[i]);
i+=1;
});
app.intent('FifthIntent', (conv) => {
conv.ask(ques[i]);
i+=1;
conv.close('Goodbye!')
});
// Set the DialogflowApp object to handle the HTTPS POST request.
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
Output
Output2
INVALID INTENT NAME ERROR
I suspect that the issue is that i never actually gets updated.
You treat ques and i as global object, but since this is running under Firebase Cloud Functions, each call may be a new instance of the function. As a new instance, these would get reinitialized.
The flip side of this is that if you didn't get a new instance, it also has the problem that this would not work correctly if more than one person was using the Action at the same time since they would all be sharing the same value of i.
The solution to both is that, instead of storing i as a global variable, store it either in the Actions on Google session storage or in a Dialogflow context parameter.
Storing it as a session parameter, you would get the value, use it, increment it, and then save it again in the session parameter. It might look something like this:
const i = conv.data.i;
conv.ask(ques[i]);
conv.data.i = i+1;

Why does ReactRouter's Route path ":params" read as "styles.css" in express?

I am using Reactrouter in my front end and Express in my back end.
When I am routing with custom parameters which im using for a findbyID fetch for a component, I found
through my error log on express side read the custom param as styles.css.
React Rounter Side:
<Route path="/id/:id" component={Something} />
On Express:
app.get("/id/:id", (req, res) => {
const id = req.params.id;
database.findById(id, (e, found) => {
console.log(id);
if (!e) {
console.log(found);
} else {
console.log(e);
console.log("consult stack overflow");
}
});
});
Error Message:
MongooseError [CastError]: Cast to ObjectId failed for value "styles.css" at path "_id" for model "database"
Why does it do this and how can I fix it?
So as it turns out I have a Link to a styles.css in my index html page. soon as i removed that everything worked the way it should have. So if anyone Is stuggling with this exact same issue later down the line here's hoping this helps you. Check your index.html file for any matching names.

Angular2 return data from validation service after Http call

I have build a validation service for my registration form and one of the static methods is checking if the entered email is available by calling my API the following:
static emailAvailable(control){
let injector = ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]);
let http = injector.get(Http);
let valid = "E-mail is available";
http.post('https://secretapi.com/email', JSON.stringify({ email: control.value }))
.map((res: Response) => res.json())
.subscribe(function(result){
if(result.success){
valid = result.success; //The console.log on the line below is correct, the one at the bottom of the script never changes.
console.log(valid);
return null; //Doesn't do anything?
}else{
valid = result.error; //The console.log on the line below is correct, the one at the bottom of the script never changes.
console.log(valid);
return { 'invalidEmailAddress': true }; //Doesn't do anything, just like the return above
}
});
console.log(valid); //Output always "E-mail is available"
}
It should return "null" to the form validator when the email is available. The last console.log at the bottom should output the message that it recieves in the subscribe call. This doesn't happen and I'm not sure why. For some reason everything that happens within the subscribe call is contained there and never reaches the validator. What should I change? I have no idea and been searching the web for hours now.
You have to return Observable or Promise from your validator:
return http.post('https://secretapi.com/email', ...
console.log(...) doesn't make any sense here, since it will be executed after the Observable has been created as an object, but not after the ajax call has bee made.
If you want to output something after a response has been received, you have to move it inside subscribe
So in the end this website had the right answer. Also important to notice with the Angular2 Form validator to put the Async validators in the third (3) parameter and not together in an array in the second (2) parameter. That took me about 3 hours to figure out.
function checkEmail(control: Control){
let injector = ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]);
let http = injector.get(Http);
return new Observable((obs: any) => {
control
.valueChanges
.debounceTime(400)
.flatMap(value => http.post('https://secretapi.com/email', JSON.stringify({ email: control.value })))
.map((res: Response) => res.json())
.subscribe(
data => {
if(data.success){
obs.next(null);
obs.complete();
} else {
obs.next({ 'invalidEmailAddress': true });
obs.complete();
}
}
);
});
}
The validator should look something like this, with the first validators checking on required and if it's actually an email address and the last doing an async call to the server to see if it's not already in use:
this.registerForm = this.formBuilder.group({
'email': ['', [Validators.required, ValidationService.emailValidator], ValidationService.emailAvailable],
});