issue I have developed own API which generates and refreshes token using directline api. The problem is after that when I integrated token instead of Secret in above code, my bot replies the answer correctly but also echo back the input which is being provided. There is no such implementation done in code and with secret and emulator all works fine.
(function () {
$('head').append('<link rel="stylesheet" type="text/css" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/9.6.0/css/fabric.min.css">');
$('head').append('<link rel="stylesheet" type="text/css" href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css">');
$('head').append('<link rel="stylesheet" type="text/css" href="chatbot.css">');
var chatIsVisible = false;
$(function () {
$(".botwrapper").toggle();
$('<i class="ms-Icon ms-Icon--ChromeMinimize minimizeIcon" aria-hidden="true"></i>').appendTo(".wc-header");
$("#botbutton").click(function () {
chatIsVisible = true;
$("#botbutton").toggle("fade", function () {
$("#BotChatGoesHere").toggle("fade", function () {
$(".chatbot .wc-shellinput").focus();
});
});
});
$(".wc-header .minimizeIcon").click(function () {
$("#BotChatGoesHere").toggle("fade", function () { $("#botbutton").toggle("fade"); chatIsVisible = false; });
});
setTimeout(showBot, 3000);
setInterval(shakeBot, 10000);
function showBot() {
$("#botbutton").toggle("fade").effect("bounce", { times: 3 }, "slow");
}
function shakeBot() {
if (!chatIsVisible) {
$("#botbutton").effect("bounce", { times: 3 }, "slow");
}
}
});
const params = BotChat.queryParams(location.search);
const user = {
id: params['userid'] || 'userid',
name: params['username'] || 'User'
};
const bot = {
id: params['botid'] || 'SAM',
name: params['botname'] || 'SAM'
};
const speechOptions = {
speechRecognizer: new CognitiveServices.SpeechRecognizer({ locale: 'de-DE', subscriptionKey: '' }),
speechSynthesizer: new CognitiveServices.SpeechSynthesizer({
gender: CognitiveServices.SynthesisGender.Female,
subscriptionKey: '',
voiceName: 'Microsoft Server Speech Text to Speech Voice (de-DE, Stefan, Apollo)'
})
};
window['botchatDebug'] = params['debug'] && params['debug'] === 'true';
function ConnectWebBotChat() {
let headers = {
};
if (botConnection !== null) {
// for refresh token
headers = {
old_token: TokenResult.token,
user_id: TokenResult.userId
};
}
$.ajax({
url: "http://localhost:64102/api/DLToken",
//async: "false",
method: "POST",
data: "",
dataType: 'json',
contentType: "application/json",
headers: headers,
success: function (result, status, jqXHR) {
TokenResult = result;
botConnection = new BotChat.DirectLine({
domain: params['domain'],
secret: result.token,
token: result.token,
webSocket: params['webSocket'] && params['webSocket'] === 'true'
});
BotChat.App({
bot: bot,
resize: 'detect',
user: user,
speechOptions: speechOptions,
directLine: botConnection
}, document.getElementById('BotChatGoesHere'));
PingBotConnection(true);
console.log("SAM Connection Refreshed : " + status);
},
error(jqXHR, textStatus, errorThrown) {
console.log("SAM Connection Refresh : " + errorThrown);
}
});
}
function PingBotConnection(_IsFirstTime = false) {
botConnection
.postActivity({
from: user,
name: 'Connection Test',
type: 'event',
value: ''
})
.subscribe(function (id) {
console.log('SAM Pinged OK!');
});
botConnection.connectionStatus$
.subscribe(connectionStatus => {
handleConnection(connectionStatus);
if (!_IsFirstTime)
ConnectWebBotChat();
});
}
function handleConnection(connectionStatus) {
switch (connectionStatus) {
case 0:
console.log("SAM Uninitialized");
break;
case 1:
console.log("SAM Connecting");
break;
case 2:
console.log("SAM Online");
break;
case 3:
console.log("SAM ExpiredToken");
break;
case 4:
console.log("SAM FailedToConnect");
break;
case 5:
console.log("SAM Ended");
break;
}
}
let botConnection = null;
let TokenResult = null;
ConnectWebBotChat();
setInterval(() => { PingBotConnection(false); }, 1780000);
})();
Bot should not echo back the inputted message on use of Directline Token.
Many thanks in Advance
Looking at the above posted code, it looks like you are passing the token as a secret. I would recommend you just pass one not both.
Also, I would recommend you to upgrade to web chat v4 as it provides more support when it comes to customization. This sample provides a detailed guide on how to migrate from Web Chat v3 to v4.
Related
I tried to define the url which opens when user click on notification but it continue go to url('/')
only . I send the new url with payload.data but I did not know where I can define this route in the client side so it opens when user click notification .
I use laravel-notification-channels/fcm
/**
* #param Model $notifiable
* #return FcmMessage
*/
final public function toFcm(Model $notifiable): FcmMessage
{
return FcmMessage::create()
->setData(array_merge(['type' => $this->fcmNotification->type],$this->fcmNotification->data)
)->setNotification(\NotificationChannels\Fcm\Resources\Notification::create()
->setTitle($this->fcmNotification->title)
->setBody($this->fcmNotification->body)
->setImage($this->fcmNotification->image)
) ->setAndroid(
AndroidConfig::create()
->setFcmOptions(AndroidFcmOptions::create()->setAnalyticsLabel('analytics'))
->setNotification(AndroidNotification::create()->setColor('#0A0A0A'))
)->setApns(
ApnsConfig::create()->setFcmOptions(ApnsFcmOptions::create()->setAnalyticsLabel('analytics_ios')));
}
##################### firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/7.23.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.23.0/firebase-messaging.js');
/*
firebase.initializeApp({
apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
authDomain: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
projectId: "xxxxxxxxxxxxxxxx",
storageBucket: "xxxxxxxxxxxxxxxxxx",
messagingSenderId: "xxxxxxxxxxxxxxxxxxxxx",
appId: "x",xxxxxxxxxxxxxxxxxxxxxxxxx
measurementId: "xxxxxxxxxxxxxxxx"
});
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
console.log(
"[firebase-messaging-sw.js] Received background message ",
payload,
);
/* Customize notification here */
const notificationTitle = "Background Message Title";
const notificationOptions = {
body: "Background Message body.",
icon: "/itwonders-web-logo.png",
};
return self.registration.showNotification(
notificationTitle,
notificationOptions,
);
});
##################### main layout
$(document).ready(function () {
const firebaseConfig = {
apiKey: "xxxxxxxxxxxxx",
authDomain: "x",xxxxxxxxxxxxxxxxxxxx
projectId: "xxxxxxxxxxxxxxxxxxxx",
storageBucket: "xxxxxxxxxxxxxxxxxxxx",
messagingSenderId: "xxxxxxxxxxxxxxxxxxxx",
appId: "xxxxxxxxxxxxxxxxxxxx",
measurementId: "xxxxxxxxxxxxxxxxxxxx"
};
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
function initFirebaseMessagingRegistration() {
messaging
.requestPermission()
.then(function () {
return messaging.getToken()
})
.then(function (token) {
// console.log(token);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: '{{ theme_route('save.fcm.token')}}',
type: 'POST',
data: {
token: token
},
dataType: 'JSON',
success: function (response) {
console.log('Token saved successfully.');
},
error: function (err) {
console.log('User Token Error' + err);
},
});
}).catch(function (err) {
console.log('User Chat Token Error' + err);
});
} initFirebaseMessagingRegistration();
messaging.onMessage(function (payload) {
const noteTitle = payload.notification.title;
console.log(payload.data);
const noteOptions = {
body: payload.notification.body,
icon:"{{website()->logo}}" ,
image: payload.notification.image,
};
new Notification(noteTitle, noteOptions);
self.addEventListener('notificationclick', function(event) {
event.notification.close();
console.log('test click event');
event.waitUntil(self.clients.openWindow('#'));
});
});
});```
I figured that I should look for " PushEvent " : I used this two listeners to handle user clicks on FCM web push notifications, in your service worker firebase-messaging-sw.js place the following
two listeners (of course change them depending on your data) :
self.addEventListener("push", (event) => {
console.log(event);
let response = event.data && event.data.text();
let title = JSON.parse(response).notification.title;
let body = JSON.parse(response).notification.body;
let icon = JSON.parse(response).notification.image;
let image = JSON.parse(response).notification.image;
event.waitUntil(
self.registration.showNotification(title, { body, icon, image, data: { url: JSON.parse(response).data.url } })
)
});
self.addEventListener('notificationclick', function(event) {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
});
The notification is showing fine, but when I click on it, or any of the actions, nothing happens. I see no logging, no error messages, but the notification does close (although it closes even when I comment out the event.notification.close()).
I've tried using the Chrome debugger, and I can set a break point in the code that shows the notification, but all breakpoints within the notificationclick handler fail to pause execution.
I've spent days trying to get this to work and I'm at my wits' end.
const auth = firebase.auth();
const functions = firebase.functions();
const done = functions.httpsCallable("done");
const snooze = functions.httpsCallable("snooze");
self.addEventListener("notificationclick", event => {
console.log("notificationclick", event);
const uid = auth.currentUser.uid;
const { id, url } = event.notification.data;
event.notification.close();
event.waitUntil(() => {
switch (event.action) {
case "done":
console.log("Done");
return done({ uid, id });
case "snooze1":
console.log("Snooze 1 Hour");
return snooze({ uid, id, hours: 1 });
case "snooze24":
console.log("Snooze 1 Day");
return snooze({ uid, id, hours: 24 });
default:
console.log("Open App");
return clients
.matchAll({
includeUncontrolled: true,
type: "window"
})
.then(clientList => {
for (let i = 0; i < clientList.length; i++) {
let client = clientList[i];
if (url[0] === "#") {
if (client.url.endsWith(url) && "focus" in client) {
return client.focus();
}
} else {
if (
client.url.replace(/#.*$/, "") === url &&
"focus" in client
) {
return client.focus();
}
}
}
if (clients.openWindow) {
return clients.openWindow(location.origin + url);
}
});
}
});
});
firebase
.messaging()
.setBackgroundMessageHandler(({ data: { title, options } }) => {
options = JSON.parse(options);
options.actions = [
{ action: "done", title: "Done" },
{ action: "snooze1", title: "Snooze 1 Hour" },
{ action: "snooze24", title: "Snooze 1 Day" }
];
return self.registration.showNotification(title, options);
});
Hi Could you try below code and see if this is getting called-
self.addEventListener('notificationclick', function (event) {
event.notification.close();
var redirectUrl = null;
var tag = event.notification.tag;
if (event.action) {
redirectUrl = event.action
}
if (redirectUrl) {
event.waitUntil(async function () {
var allClients = await clients.matchAll({
includeUncontrolled: !0
});
var chatClient;
for (const client of allClients) {
if (redirectUrl != '/' && client.url.indexOf(redirectUrl) >= 0) {
client.focus();
chatClient = client;
break
}
}
if (chatClient == null || chatClient == 'undefined') {
chatClient = clients.openWindow(redirectUrl);
return chatClient
}
}().then(result => {
if (tag) {
//PostAction(tag, "click")
}
}))
}
});
Edited-
Attaching both js files. it is working at my end.
firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');
var config = {
apiKey: "your api key",
authDomain: "you firebase domain",
databaseURL: "your firbase db url",
projectId: "your project id",
storageBucket: "",
messagingSenderId: "sender id"
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function (payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload.data);
var notificationTitle = payload.data.Title;
var notificationOptions = {
body: payload.data.Body,
icon: payload.data.Icon,
image: payload.data.Image,
action: payload.data.ClickAction
};
console.log("strated sending msg" + notificationOptions);
return self.registration.showNotification(notificationTitle,notificationOptions);
});
self.addEventListener('notificationclick', function (event) {
console.log('On notification click: ', event.notification);
event.notification.close();
var redirectUrl = null;
if (event.notification.data) {
if (event.notification.data.FCM_MSG) {
redirectUrl = event.notification.data.FCM_MSG.data ? event.notification.data.FCM_MSG.data.click_action : null
} else {
redirectUrl = event.notification.data ? event.notification.data.click_action : null
}
}
console.log("redirect url is : " + redirectUrl);
if (redirectUrl) {
event.waitUntil(async function () {
var allClients = await clients.matchAll({
includeUncontrolled: true
});
var chatClient;
for (var i = 0; i < allClients.length; i++) {
var client = allClients[i];
if (client['url'].indexOf(redirectUrl) >= 0) {
client.focus();
chatClient = client;
break;
}
}
if (chatClient == null || chatClient == 'undefined') {
chatClient = clients.openWindow(redirectUrl);
return chatClient;
}
}());
}
});
self.addEventListener("notificationclose", function (event) {
event.notification.close();
console.log('user has clicked notification close');
});
application.js file :
/// <reference path="scripts/jquery-3.3.1.js" />
try {
var config = {
apiKey: "your api key",
authDomain: "you firebase domain",
databaseURL: "your firbase db url",
projectId: "your project id",
storageBucket: "",
messagingSenderId: "sender id"
};
firebase.initializeApp(config);
if ('serviceWorker' in navigator && 'PushManager' in window) {
console.log('Service Worker and Push is supported');
navigator.serviceWorker
.register('/firebase-messaging-sw.js')
.then((swReg) => {
firebase.messaging().useServiceWorker(swReg);
askForPermissioToReceiveNotifications();
})
.catch(function (error) {
console.error('Service Worker Error', error);
window.alert("Service Worker Error" + error);
})
} else {
console.warn('Push messaging is not supported');
window.alert("Push messaging is not supported " + (navigator.serviceWorker));
}
const askForPermissioToReceiveNotifications = async () => {
try {
const messaging = firebase.messaging();
console.log(messaging);
await messaging.requestPermission();
const token = await messaging.getToken();
if (token !== null || token !== 'undefined') {
await sendDeviceTokenToServerSide(token);
}
console.log('Got token : ' + token);
messaging.onMessage(function (payload) {
console.log('onMessage: ', payload);
setTimeout(() => {
navigator.serviceWorker.ready.then(function (registration) {
var notificationTitle = payload.notification.title;
var notificationOptions = {
body: payload.notification.body,
data: payload.data,
icon: payload.notification.icon,
image: payload.data.Image,
requireInteraction: payload.notification.requireInteraction,
tag: payload.notification.tag,
click_action: payload.data.click_action,
requireInteraction: true
};
registration.showNotification(notificationTitle, notificationOptions);
},50)
});
});
}
catch (e) { console.log('error in getting token: ' + e); window.alert("error in getting token: " + e); }
}
function sendDeviceTokenToServerSide(token) {
$.ajax({
type: 'POST',
url: '/Home/StoreToken',
timeout: 5000000,
data: { token: token },
success: function (success) {
console.log("device token is sent to server");
},
error: function (error) {
console.log("device error sending token to server : " + error);
window.alert("device error sending token to server : " + error);
}
});
}
} catch (e) {
window.alert("error: " + e);
}
function GetFcmUserToken(messaging) {
messaging.onTokenRefresh(function () {
messaging.getToken()
.then(function (refreshedToken) {
console.log('Token refreshed.');
return refreshedToken;
})
.catch(function (err) {
console.log('Unable to retrieve refreshed token ', err);
showToken('Unable to retrieve refreshed token ', err);
});
});
}
self.addEventListener('notificationclick', function (event) {
const clickedNotification = event.notification;
// Do something as the result of the notification click
const promiseChain = clients.openWindow(clickedNotification.data.Url);
event.waitUntil(promiseChain);
});
This code inside service worker js worked fine for me on chrome Desktop and Android.
I am using hapijs version 17.0.1. I am trying to upload an image using ajax request on a hapijs route. Here is my AJAX code to upload profile pic:
var image_file_input = document.getElementById("user_profile_upload");
image_file_input.onchange = function () {
if(this.files != undefined)
{
if(this.files[0] != undefined)
{
var formData = tests.formdata ? new FormData() : null;
if (tests.formdata)
{
//alert(file)
formData.append('image_file', this.files[0]);
formData.append('userId', user_id);
formData.append('memberId', member_id);
}
$.ajax({
url: "/v1/User/uploadUserPic",
data: formData,
type: "POST",
dataType: "json",
contentType: false,
processData: false,
contentType: "multipart/form-data",
success: function(data){
console.log(data);
var errMsg = null;
var resData = null;
if(data.statusCode == 200)
{
resData = data.result;
}
else
{
alert(data.message)
}
},
error: function(error){
alert(error);
}
});
}
}
}
And here is my Hapijs route Code:
var uploadUserPic = {
method: 'POST',
path: '/v1/Module/uploadUserPic',
config: {
description: 'Update Image For User',
tags: ['api', 'User'],
auth: 'session',
payload: {
output: 'stream',
parse: true,
allow: 'multipart/form-data'
},
validate: {
payload: {
userId : Joi.string().regex(/^[a-f\d]{24}$/i).required(),
memberId: Joi.string().required(),
image_file: Joi.object().required(),
},
failAction: FailCallBack
}
},
handler: function (request, reply) {
var resultData = null;
var error = null;
return new Promise(function (resolve) {
var multiparty = require('multiparty');
var fs = require('fs');
var form = new multiparty.Form();
form.parse(request.payload, function (err, fields, files) {
if(err)
{
error = err;
resolve();
}
else
{
var mkdirp = require('mkdirp');
var img_dir = "./files/users/";
mkdirp(img_dir, function (err) {
if (err)
{
error = err;
console.error(err);
resolve();
}
else
{
var oldpath = files.image_file.path;
var newpath = "./files/users/"+requestPayload.userId+".png";
fs.rename(oldpath, newpath, function (err) {
if(err)
{
error = err;
}
resolve();
});
}
});
}
});
}).then(function (err, result) {
if(err) return sendError(err);
if(error) return sendError(error)
return {
"statusCode": 200,
"success": true
};
});
}
}
The above code gives me following error cannot read property 'content-length' of undefined on line form.parse(request.payload, function (err, fields, files) {});
Please let me know If I am doing something wrong. If I replace the url in ajax request with anohter url that I have written in php then it works perfectly. which means that something is wrong with my hapijs/nodejs code.
There's a good post on how to handle file uploads in Hapi.js (written in version 16) https://scotch.io/bar-talk/handling-file-uploads-with-hapi-js
Since you are using payload.parse = true, I am not seeing a particular reason why you have to use multiparty. I have the following working code that would save files (of any type) uploaded from client into uploads directory on the server (Please do not use directly on production as no sanitation is done)
{
path: '/upload',
method: 'POST',
config: {
payload: {
output: 'stream',
parse: true,
allow: 'multipart/form-data'
},
validate: {
payload: {
files: Joi.array().single()
}
}
},
handler: function(request) {
const p = request.payload, files = p.files
if(files) {
console.log(`${files.length} files`)
files.forEach(async file => {
const filename= file.hapi.filename
console.log(`Saving ${filename} to ./uploads`)
const out = fs.createWriteStream(`./uploads/${filename}`)
await file.pipe(out)
})
}
return {result: 'ok'}
}
}
You can use the following curl command to test
curl http://localhost:8080/upload -F 'files=#/path/to/a/note.txt' -F 'files=#/path/to/test.png' -vvv
There are a few issues with your code. First in your $.ajax call, you have specified contentType twice, although it's not a syntax error but it's careless to code like that. Second the function's signature inside your .then() block is incorrect. You are mixing the idea of Promise and callback. I don't think the following line will be triggered
if(err) return sendError(err);
One last trivial thing, you said you are using Hapi 17 but based on the handler function's signature
handler: function (request, reply) {
...
Seems you are not totally onboard with Hapi17 as the new signature is
handler: function (request, h) {
And it's not just the rename of reply to h.
I need send mails with nodemailer using ajax for show a message confirmation, with out reload my page.
other problem is if using the code ajax in the frontend send two mails
============================
app.js
app.post('/enviar', function(req,res){
var name = req.body.nombre;
var mail = req.body.correo;
var messege = req.body.mensaje;
var mail_from = "servicios#fractalservicios.com";
var subject_from = "Contact web fractal nodejs";
var transporter = nodemailer.createTransport(smtpTransport({
host: "*****",
port: ***,
auth: {
user: "****",
pass: "****"
}
}));
var mailOptions = {
from: name + ' ' + mail, // sender address
to: mail_from, // list of receivers
subject: subject_from , // Subject line
html: messege // html body
};
transporter.sendMail(mailOptions,function(error,result){
if(error){
console.log(error);
console.log("salio mal");
//res.end("error");
res.render('error',{titulo: 'error al enviar menmsaje'});
}else{
console.log("Message sent: " + res.message);
console.log("correcto");
res.redirect('/');
//res.render('enviado',{titulo: 'mensaje enviado'});
}
//res.redirect('/');
});
})
build.js => Front-end
var nombre = $('#nombre').val();
var correo = $('#correo').val();
var mensaje = $('#mensaje').val();
var enviar_info = {
"nombre": nombre,
"correo": correo,
"mensaje": mensaje
};
$('.send_mail').on('click',function(){
$.ajax({
type: "POST",
url: "/enviar",
data: JSON.stringify(enviar_info),
contentType:"application/json; charset=utf-8",
dataType: 'json',
success: function(e){
alert("genial se envio tu mensaje");
}
});
});
I recently ran into the same issue and I tried the following way. It worked like a magic for me, late answer but, I am sure someone else might need it...
$(function() {
$('#contact-form').on('submit', function(event) {
event.preventDefault();
let name = $('input[name="name"]').val(),
company = $('input[name="company"]').val(),
email = $('input[name="email"]').val(),
phone = $('input[name="phone"]').val(),
message = $('textarea[name="message"]').val();
$.ajax({
url: '/',
method: "POST",
contentType: 'application/json',
data: JSON.stringify({
name,
company,
email,
phone,
message
}),
success: function(response) {
console.log(response);
},
fail: function(error) {
console.log(error);
}
});
});
});
and in server.js
app.post('/', function(req, res) {
const output = `
<p>You have a new contact request</p>
<h3>contact details</h3>
<ul>
<li>Name: ${req.body.name}</li>
<li>Company: ${req.body.company}</li>
<li>Email: ${req.body.email}</li>
<li>Phone: ${req.body.phone}</li>
</ul>
<h3>Message</h3>
<p>${req.body.message}</p>
`;
let transporter = nodemailer.createTransport({
service: 'gmail',
host: 'mail.domain.com',
port: 465,
tls: {
rejectUnauthorized: false, //NOTE: you only need to set rejectUnauthorized to false if you are running on a local server, you can remove it after testing
}
});
let mailOptions = {
from: `nodemailer contact ${req.body.email}`,
to: 'info#domain.com',
subject: 'User Form Contact',
html: output
};
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
return console.log(error);
}
console.log('Message sent: %s', info.messageId);
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
res.send({
msg: 'Email has been sent!'
});
});
});
I am trying to do the following from my HTML:
var vm = new Vue({
el: '#loginContent',
data: {
main_message: 'Login',
isLoggedIn: false,
loginError: '',
loginButton:'Login'
},
methods: {
onLogin: function() {
//this.$set(loginSubmit, 'Logging In...');
var data = {
email: $('#email').val(),
password: $('#password').val(),
};
$.ajax({
url: '/api/login',
data: data,
method: 'POST'
}).then(function (response) {
if(response.error) {
console.err("There was an error " + response.error);
this.loginError = 'Error';
} else {
//$('#loginBlock').attr("hidden",true);
console.log(response.user);
if(response.user) {
this.isLoggedIn = true;
} else {
this.loginError = 'User not found';
}
}
}).catch(function (err) {
console.error(err);
});
}
}
});
Basically user presses the login button, onLogin method is called that sends a post to my API. The post is working fine and I do get the response back in the .then() promise.
But, trying to do things like this.isLoggedIn = true; does not update my DOM with what I am expecting the HTML to do when the user logs in.
Could be that I am in some sort of background thread (sorry, mobile developer here) when I get the response in the promise and it can't find the "vm" instance?
Thanks
It is probably happening because your this is not pointing to correct scope, scope of this changes inside an $.ajax call, so you just have to do something like following:
methods: {
onLogin: function() {
//this.$set(loginSubmit, 'Logging In...');
var data = {
email: $('#email').val(),
password: $('#password').val(),
};
var that = this
$.ajax({
url: '/api/login',
data: data,
method: 'POST'
}).then(function (response) {
if(response.error) {
console.err("There was an error " + response.error);
that.loginError = 'Error';
} else {
//$('#loginBlock').attr("hidden",true);
console.log(response.user);
if(response.user) {
that.isLoggedIn = true;
} else {
that.loginError = 'User not found';
}
}
}).catch(function (err) {
console.error(err);
});
}
}
I would propose another method use ES6 Arrow Functions like '=>'. It is simple and do not need extra variable.Like following:
$.ajax({
url: '/api/login',
data: data,
method: 'POST'
}).then((response) => {
if(response.error) {
console.err("There was an error " + response.error);
this.loginError = 'Error';
} else {
//$('#loginBlock').attr("hidden",true);
console.log(response.user);
if(response.user) {
this.isLoggedIn = true;
} else {
this.loginError = 'User not found';
}
}
}).catch(function (err) {
console.error(err);
});
You might want to take a look at axios. I used $.ajax and got it working, but found axios and prefer axios over the ajax library.