Hapi.js reply.redirect() is not working after image upload - hapi.js

I have the following code, in my server. I'm uploading an image using mongoose and s3 and then want to redirect the user to another page but this isn't happening. (the upload is successful).
Routes.js:
{path: '/success', method: 'GET', config: controller.success} ......
controller.js:
imageUpload: {
payload: {
maxBytes: 209715200,
output: 'file',
parse: true
},
handler: function(request, reply) {
var userName = request.auth.credentials.username;
members.findMemberByUsername(userName, function(err, member){
if (err) {
return reply.view('upload', {error: err});
} else if (member) {
var IDImagePath = request.payload.uploadedIDname.path;
console.log(IDImagePath);
members.addID(member, IDImagePath, function(err1){
console.log("add id error", err1);
if (err1){
return reply.view('upload', {error: err1, member: member});
} else {
console.log("SUCCESSFUL!");
return reply.redirect('/success');
}
});
}
});
}
},
success: {
handler: function (request, reply){
request.auth.session.clear();
console.log("success handler working!!");
return reply.view('success');
}
}
The code hits both console.log("SUCCESSFUL") and console.log("success handler working!!") in the controller but the redirect doesn't take place. By the way I'm using 'Jade' as the templating language so I have a success.jade. Thanks.

I found out what the problem was. I'm using AJAX on the client side but didn't have a 'success' method to reload the page:
$('#submitID').click(function(){
var formData = new FormData($('#uploadID')[0]);
$.ajax({
url: '/api/image',
type: 'POST',
xhr: function() { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
console.log(myXhr.upload);
}
return myXhr;
},
success: function(data) {
window.location.href = "/success"
},
data: formData,
cache: false,
contentType: false,
processData: false
}, "json");
});
I needed window.location.href = "/success" to reload the page. Please note the jQuery Ajax SUCCESS method is different to my '/success' route, they just happen to be the same word.

Related

Catch error server response with #nuxtjs/auth

I'm trying to catch the error response for #nuxtjs/auth but it doesn't seem to return anything but undefined.
It refuses to login if I include the user so I want to know why it's returning undefined.
CONFIG:
auth: {
strategies: {
local: {
endpoints: {
login: {
url: 'http://127.0.0.1:80/api/login',
method: 'post',
propertyName: 'token'
},
logout: false,
user: {
url: 'http://127.0.0.1:80/api/me',
method: 'get',
propertyName: undefined
}
},
tokenRequired: true,
tokenType: 'bearer',
}
},
plugins: [
'#/plugins/auth.js'
]
},
PLUGIN:
export default function ({ app }) {
app.$auth.onError((error, name, endpoint) => {
console.error(name, error)
});
}
VIEW FUNCTION:
- both handleSuccess and handleFailure returns undefined.
login() {
this.toggleProcessing(0);
let payload = {
username: 'admin',
password: 'admin123'
}
let handleSuccess = response => {
console.log(response);
this.toggleProcessing(0);
}
let handleFailure = error => {
console.log(error);
this.toggleProcessing(0);
}
this.$auth.loginWith('local', { data: payload }).then(handleSuccess).catch(handleFailure);
},
You can use e.response
async login() {
try {
const login = {
username: this.username,
password: this.password
}
let response = await this.$auth.loginWith('local', { data: login })
console.log('response', response)
} catch (e) {
console.log('Error Response', e.response)
}
}
I fell into the same problem and after spending some time i found out a very good way to catch the response. The solution is to use the axios interceptor. Just replace your plugin file code with the following
export default function ({$axios, $auth}){
$axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
}
I'm not sure initially what might be wrong here because I can't see the complete nuxt.config.js and your full component but here are a few things to check:
#nuxtjs/axios is installed
Both axios and auth modules are registered in the modules section of nuxt.config.js:
modules: [
'#nuxtjs/axios',
'#nuxtjs/auth'
]
Also, ensure the middleware property for auth is set in the component/page component.
Ensure you're following the documentation on this page: https://auth.nuxtjs.org/getting-starterd/setup
Ive been using try -> this.$auth.loginWith to catch error server response with #nuxtjs/auth.
login() {
const data = { form };
try {
this.$auth
.loginWith("local", { data: data })
.then(api => {
// response
this.response.success = "Succes";
})
.catch(errors => {
this.response.error = "Wrong username/password";
});
} catch (e) {
this.response.error = e.message;
}
},
Specify the token field in the nuxt.config
strategies: {
local: {
endpoints: {
login: { // loginWith
url: "auth/login",
method: "post",
propertyName: "data.token" // token field
},
user: { // get user data
url: "auth/user",
method: "get",
propertyName: "data.user"
},
}
}
},
modules: ["#nuxtjs/axios", "#nuxtjs/auth"],

Vee-validate (VueJS) - evaluating a condition asynchronously

Can I make a custom validation rule that returns true/false based on a AJAX request? the problem is that the validate call has finished running when the AJAX call completes.
Do I need to have the rule set/unset a boolean variable based on which the field is valid/invalid?
const isValidNameRule = {
getMessage(field)
{
return "The name must be unique."
},
validate(validatingName)
{
var formData = new FormData();
formData.append("validatingName", validatingName);
this.$http.post("/api/isValid?name=" + validatingName, formData)
.then(function (response) {
// success
return true;
}, function (response) {
// error
return false;
});
}
};
Didn't know how to work with Promises.
Eventually got it working by extending one of the official samples:
const customRule = {
getMessage(field, params, data) {
return (data && data.message) || 'Something went wrong';
},
validate(aValue) {
return new Promise(resolve => {
var formData = new FormData();
formData.append("nameFilter", aValue);
$.ajax({
type: "POST",
url: url,
data: {
action: "validate",
value: aValue,
}
}).done(function (data) {
if (!ok)
{
resolve({
valid: false,
data: {message: "Condition not met"}
});
}
else
{
resolve({
valid: !! aValue,
data: undefined
});
}
});
});
}
};

How to read the POST data inside the template in JSREPORT

I have the following request to the jsreport engine:
$.ajax({
method: "POST",
contentType: "application/json",
dataType: "jsonp",
url: "http://localhost:5488/api/report",
data: {
template: {
shortid: "ry6HoQRee"
},
data: {
"D": "5"
}
},
success: function (s) {
window.open("data:application/pdf,base64," + escape(s.responseText));
},
error: function (s) {
console.log(s);
}
});
However I can't find a way to read it inside the report template:
<span>{{data.D}}</span>
How do I refer to the data object that is inside the POST body
jquery doesn't support binary responses like pdf. You should rather use XMLHttpRequest:
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://localhost:5488/api/report', true)
xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8')
xhr.responseType = 'arraybuffer'
xhr.onload = function(e) {
if (this.status == 200) {
window.open("data:application/pdf;base64," + window.btoa(String.fromCharCode.apply(null, new Uint8Array(xhr.response))));
}
}
xhr.send(JSON.stringify({
template: {
shortid: 'Syeopu_xe'
},
data: {
'D': '5'
}
}))
Example of reaching data using handlebars templating engine
<span>{{D}}</span>
Additionally...
You may also take a look at jsreport official browser client library. It wraps the XmlHttpRequest calls into more elegant calls:
jsreport.serverUrl = 'http://localhost:3000';
var request = {
template: {
content: 'foo', engine: 'none', recipe: 'phantom-pdf'
}
};
//display report in the new tab
jsreport.render('_blank', request);
or in async fashion
jsreport.renderAsync(request).then(function(res) {
//open in new window
window.open(res.toDataURI())
//open download dialog
res.download('test.pdf')
});

how to handle error 401 in simple ember auth?

The problem is the session will expire after a predetermined amount of time. Many times when this happens the ember.js app is still loaded. So all requests to the backend return a 401 {not autorized} response.
so i need to redirect user to the login page and clear the last token from the session so that isauthenticated property becomes false.
I am using custom authenticator.
import Base from 'ember-simple-auth/authenticators/base';
import ENV from '../config/environment';
import Ember from 'ember';
export default Base.extend({
restore: function(data) {
return new Ember.RSVP.Promise(function (resolve, reject) {
if (!Ember.isEmpty(data.token)) {
resolve(data);
}
else {
reject();
}
});
},
authenticate: function(options) {
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
type: "POST",
contentType: 'application/json',
url: ENV.CONSTANTS.API_URL + '/authentication',
data: JSON.stringify({
username: options.username,
password: options.password
})
}).then(function(response) {
if(!response.token){
Ember.run(function(){
reject(response.message);
});
} else {
Ember.run(function() {
resolve(response);
});
}
}, function(xhr, status, error) {
Ember.run(function() {
reject(xhr.responseJSON || xhr.responseText);
});
});
});
},
invalidate: function(data) {
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
type: "GET",
url: ENV.CONSTANTS.API_URL + '/authentication/logout'
}).then(function(response) {
Ember.run(function() {
resolve(response);
});
}, function(xhr, status, error) {
Ember.run(function() {
reject(xhr.responseJSON || xhr.responseText);
});
});
});
}
});
I am using ember simple auth 1.0.0. Anybody have a working solution to this problem?
If you're using the DataAdapterMixin that will automatically handle all 401 response to Ember Data requests and invalidate the session if it gets one. If you're making your own AJAX requests you'd have to handle these responses yourself.
Automatic authorization of all requests as well as automatic response handling was removed in 1.0.0 as it lead to a lot of problems with global state and made the whole library much harder to reason about.

How to pass Client Side data to Server Side using Ember.js

I'm studying Ember.js myself and I'm stuck with a problem I'm creating a sample app and I need to send the client side values to Server Side but I dont know how to do that I know the traditional way like the below code
function create() {
var data = {
'EmailID': $('#emailid').val(),
'password': $('#password').val()
}
$.ajax({
url: '/EmberNew/Home/Create',
type: 'POST',
data:data,
success: function (response) {
alert("hi");
}
});
return false;
}
but In Ember i dont Know How to do that my current code is given below
//Application
App = Em.Application.create();
//Model
App.Users = Em.Object.extend({
name: null,
password:null
});
//View
App.UserTextField = Em.TextField.extend({
insertNew: function () {
App.alertController.alertDetails();
}
});
App.PassTextField = Em.TextField.extend({
insertNew: function () {
App.alertController.alertDetails();
}
});
//controller
App.AlertController = Em.ObjectController.extend({
content: [],
username: '',
password: '',
alertDetails: function () {
var me = this;
var username = me.get("username");
var password = me.get("password");
alert('The User Name Is' + 'username' + 'And Password Is' + 'password');
}
});
App.alertController = App.AlertController.create();
I got the textbox values from alertDetails function and how can I pass them to server side
App.Record = Ember.Object.extend({
name: '',
other: ''
}).reopenClass({
records: [],
find: function() {
var self = this;
$.ajax({
url: "/api/records/",
type: "GET",
cache: false,
dataType: "json",
beforeSend: function() {
//if you want to call this often and need to clear + reload it
return self.records.clear();
},
success: function(results) {
var result;
for (_i = 0, _len = results.length; _i < _len; _i++) {
result = results[_i];
self.records.push(self.records.addObject(App.Record.create(result)));
}
},
error: function() {
return alert("error: failed to load the records");
}
});
return this.records;
}
});
Now that you have your model setup, you can call it from your route model hook
App.RecordsRoute = Ember.Route.extend({
model: function() {
return App.Record.find();
}
});
The find method returns an empty array right away, your template is then bound to it. When the ajax call returns w/ success and you update that array the handlebars template will update it for you w/out any DOM or jQuery glue code