I am trying to add some animation while a type-file input is processing the file, I decided to use jQUery's ajax method to send the form data.
I noticed that the beforeSend method works, but not with the success method, but instead, the error method contains all the response sent by my node server. I tried looking for similiar question but none of them work for me.
JS:
fileForm.on('submit', function(e) {
e.preventDefault();
let formData = new FormData();
formData.append('file', $('#input-file').prop('files')[0]);
$.ajax({
url: this.action,
dataType: 'script',
cache: false,
contentType: false,
processData: false,
beforeSend: () => {
console.log('loading');
},
success: function(response) {
console.log(response); // Not logging anything
setTimeout(() => {
console.log('succeded: ' + response);
}, 500);
},
error: (err) => {
console.log(err); // This logs the response
},
data: formData,
type: this.method.toUpperCase()
});
});
Node.JS:
router.post('/image', upload.single('file'), async (req, res) => {
if (req.session.passport !== undefined) {
try {
console.log(req.file, req.body);
const query = {_id: req.session.passport.user};
const user = await modelAct(userModel, query, 'findOne');
// const opt = {
// query: query,
// data: {
// $set: {
// avatar_path: req.file.path
// }
// }
// };
// await modelAct(userModel, opt, 'updateOne');
res.status(200).json({fileData: req.file});
} catch(err) {
console.log(err);
if ((typeof err.message == 'string')) {
res.sendStatus(err.message);
} else {
res.sendStatus(500);
}
}
} else {
res.sendStatus(401);
}
});
Related
Trying to upload file from web application to SharePoint directory. Upon successful upload, only the filename is saved to the database. A SharePoint link is hard coded in the frontend to view the file uploaded.
Problem encountered: Sometimes the upload fails with an error message "session was expired.. Please clear the local storage." Clearing cache does not help.
importFiles: retrieves an array of all files from the database.
saveFile: adds the last successfully file name to the end of the array
clearCache: clears the input type [rename field]
var savingFile = function () {
importFiles(() => saveFile(() => clearCache(() => {
$('#modal').modal('hide');
init();
})));
Following is to upload the selected file to the SharePoint directory.
upon successfully upload, () => { savingFile(); }); is called to save the file.
upload_SP() {
if (app.selectedFile.length == 0) {
alert("please select file to upload..");
app.isLoading = false;
return;
}
_.each(app.selectedFile, function (item, index) {
var blob = item.slice(0, item.size, 'image/jpg');
app.finalFile = new File([blob], app.renameFile[index] + '.jpeg', { type: 'image/jpg' });
});
var formData = new FormData();
_.each(app.finalFile, function (file, index) {
formData.append('file-' + index, file);
});
app.sp_action(app.parentId, app.folderId, app.finalFile.name, app.finalFile,
() => { savingFile(); });
}
},
Following method takes the arguments required to upload the file to the SP.
sp_action(parentId, folderId, fileName, data, callback = null) {
$.fileUploadSP(parentId, folderId, fileName, data, function (response) {
app.isSuccessful = response.isSuccessful;
if (response == "success") {
alert("Successfully Uploaded..");
app.messageDismissCountDown = 3;
if (callback) {
callback(response);
}else {
location.reload();
}
}
else {
clearCache(() => { });
app.message = response.message;
app.isLoading = false;
window.scrollTo(0, 0);
}
});
},
Following is AJAX call made to upload the file to the SharePoint.
window.$.getPathSP = function (parentId, forlderId, fileName) {
var origin = "https://graph.microsoft.com/v1.0/drives/" + parentId + "/items/" + forlderId +
":/" + fileName + ":/content"
return origin;
};
window.$.fileUploadSP = function (parentId, forlderId, fileName, data, callback) {
$.ajax({
type: 'PUT',
url: $.getPathSP(parentId, forlderId, fileName),
headers: graphHeader,
data: data,
contentType: false,
processData: false,
async: true,
crossDomain: true,
cache: false,
success: function (response) {
success(response, function () {
if (callback) {
callback("success");
}
});
},
failure: function (response) {
alert("failed")
failure(response, "fail");
},
error: function (response) {
alert("session was expired.. Please clear the local storage.")
error(response, callback);
}
});
};
I try to call a expressJS function from view
This is my AJAX :
const classify = (name) => {
$.ajax({
type: "GET",
url: `http://localhost:3000/classify/${name}`,
success: function (response) {
//loader.hide()
if (response.message != undefined) {
alert(`${response.message}`)
window.location = response.url
}
},
});
}
$("#classify").on("click", () => {
loader.show()
wait.show()
data.hide();
const docsName = $("#nameDocs a").text();
classify(docsName);
});
And this is my router :
router.get("/classify/:name", (req, res, next) => {
let result = main(req.params.name);
console.log("Function in process");
console.log(`Get ${result}`);
console.log("Next, send to view");
setImmediate(() => {
res.send({ url: "/", message: result });
console.log("Send success");
});
});
But I'm confused because it's res.send () before the function execution has finished. So I get undefined.
My console shows like this :
Function in process
Get undefined
Next, send to view
Send success
GET /classify/pdf_1617994486865_G_PM%20No.%2011%20Tahun%202010.pdf 200 18.193 ms - 11
I don't know how good I could the write the title but it's a little bit complicated.
So I have this webpage in /music-maker endpoint which have a modal. In the modal there is an input field which takes in a user input and post it to the backend through AJAX post request. Then that user query is used to make an API request to https://example.com/api/?key=${key}&q=${query}. The result is then displayed in the webpage.
Now that part is working as it should be but the issue comes when I try to implement an infinite scrolling feature to it.
Please note at this point that the api request above returns the first page of data only and if I specify page 2 then it will return the data from page 2 of that exact query.
So whenever the user scrolls to the bottom I need to make another api request with that exact query as before but for page 2 which I am unable to accomplish. I've tried making a get AJAX request and used a global query variable to store the query from post request but it returns undefined.
Here are the endpoints of the app:
let query;
router.get('/music-maker', (req, res) => {
res.render('music-maker');
});
router.post('/music-maker', async (req, res) => {
query = encodeURI(req.body.input);
const key = '205XxXxX54825-0ab1';
try{
const url = `https://example.com/api/?key=${key}&q=${query}`;
const fullRes = await axios.get(url);
if( fullRes.status === 200 ) {
return res.json({
data: fullRes.data
});
}
}catch(err) {
res.json({
error: 'Unable to retrieve data.'
});
}
});
router.get('/music-maker/page', async (req, res) => {
console.log('1: ', query); // returns undefined
const pageQuery = req.query.q;
try{
console.log('2: ', pageQuery)
}catch(err) {
console.log(err)
}
});
Here are the AJAX requests:
const formInput = $(".searchbar input");
const userSearchInput = formInput.val();
const modalForm = $("form");
$(modalForm).submit((e) => {
e.preventDefault();
const actionUrl = $(e.target).attr("action");
$.ajax({
type: "POST",
url: actionUrl,
dataType: "json",
data: {
input: userSearchInput
},
beforeSend: function() {
$(formInput).val("");
},
success: function({ data }) {
if ( data ) {
$(".data-container").html(data);
} else if (data.error) {
$(".error-container").html(data.error);
}
},
complete: function() {
$(".loader-container").addClass("hidden");
},
});
});
// When the user scrolls to the bottom of the container, this ajax request fires
$('.data-container').on('scroll', function(e) {
const elem = $(e.currentTarget);
if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()) {
console.log(userSearchInput); // this is undefined
$.ajax({
type: "GET",
url: `/music-maker/page/`,
dataType: "json",
beforeSend: function() {
console.log('sending');
},
success: function( data ) {
console.log('incoming');
},
complete: function() {
console.log('complete');
},
});
}
});
How can I get the other pages' data of the same query by making an API request through AJAX?
update:
server part code
router.get("/music-maker/search/:query/:page", async (req, res) => {
let query = req.params.query;
let page = req.params.page;
console.log("query: " + query);
console.log("page: " + page);
return res.json({
query: req.params.query,
page: req.params.page
});
});
client/browser
let userSearchInput = "";
let pageNumber = 1;
function getMusicMaker() {
userSearchInput = $(".searchbar input").val();
userSearchInput = encodeURIComponent(userSearchInput);
const actionUrl = "/music-maker/search";
$.ajax({
url: `${actionUrl}/${userSearchInput}/${pageNumber}`,
dataType: "json",
beforeSend: function () {
$(".searchbar input").val("");
},
success: function (data) {
alert(data.query + "\n" + data.page)
}
});
}
$("form").submit((e) => {
e.preventDefault();
pageNumber = 1; // new search, reset page number
getMusicMaker();
});
$(".data-container").on("scroll", function (e) {
const elem = $(e.currentTarget);
if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()) {
pageNumber++; // set page 2,3,4,....
getMusicMaker();
}
});
I think you have multiple problems, to fix it need whole rewrite to your code (client and server) but I suggest to use single http method, POST or GET.
endpoint for static pages list:
/music-maker/1
/music-maker/2
or
/music-maker = /music-maker/page/1
/music-maker/page/2
for search
/music-maker/search/keywords
/music-maker/search/keywords/2
/music-maker/search/keywords/3
to set page number when user scroll you can do like this
let pageNumber = 1;
$('.data-container').on('scroll', function (e) {
const elem = $(e.currentTarget);
if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()) {
pageNumber++;
$.ajax({
type: "GET",
url: `/music-maker/page/${pageNumber}`,
.......
});
}
});
I want to cache ajax response into browser database so that i can retrieve the reponse from another web page of the same application.
so far i have tried but i am not able to retrieve the data from browser cache.
any help will be appreciated
this my setting.js
appsetting = {
service1: 'http://localhost:59190/api/Settings/GetConfigurationSettings',
settingsdata: {},
savesettings: function (data) {
//alert('success');
console.log(data);
appsetting.settingsdata = data;
},
getsettings: function () {
var token = { 'token': '00000000-0000-0000-0000-000000000000' };
DBconnection.fetchdata('GET', appsetting.service1, appsetting.savesettings, function () { console.log('Cannot fetch pos') }, token, true);
}
}
this is ajaxcall.js
DBconnection = {
localCache: {
timeout: 30000,
data: {},
remove: function (url) {
delete DBconnection.localCache.data[url];
},
exist: function (url) {
return !!DBconnection.localCache.data[url] && ((new Date().getTime() - DBconnection.localCache.data[url]._) < DBconnection.localCache.timeout);
},
get: function (url) {
console.log('Getting in cache for url' + url);
return DBconnection.localCache.data[url].data;
},
set: function (url, cachedData, callback) {
DBconnection.localCache.remove(url);
DBconnection.localCache.data[url] = {
_: new Date().getTime(),
data: cachedData
};
if ($.isFunction(callback)) callback(cachedData);
}
},
fetchdata: function (typeofcall, url, success, failure, header, cachedata) {
$.ajax({
type: typeofcall,
url: url,
dataType: 'json',
failure: failure,
success: success,
headers: header,
cache: cachedata
});
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.cache) {
var complete = originalOptions.complete || $.noop,
url = originalOptions.url;
//remove jQuery cache as we have our own localCache
options.cache = false;
options.beforeSend = function () {
if (DBconnection.localCache.exist(url)) {
complete(DBconnection.localCache.get(url));
return false;
}
return true;
};
options.complete = function (data, textStatus) {
DBconnection.localCache.set(url, data, complete);
};
}
});
}
}
on my webpage i am trying to call like this
var setting = appsetting.getsettings();
console.log(setting);
but i am getting undefined result.
Im trying to do a post from a .ejs page to a nodejs api.
this is the call i do
var dataSend={
from:from,
to:to,
datesStart: startDates,
datesEnd: endDates,
price: totalPriceOften,
places:JSON.stringify(placesArray),
package: pSizeOften,
transport: $('.activeFilter:eq(1) a').html().toLowerCase(),
pickupRange: pFlexOften,
dropRange: dFlexOften,
};
$.ajax({
url: location.origin + '/publishTravelOften',
headers: {
apiKey: APIKEYWEB
},
type: "POST",
data: dataSend,
dataType: "json",
async: true,
success: function (data) {
//do stuff
},
error: function (err) {
//do other stuff
}
});
the data i send is a object with this information
and in the nodejs api, i have this:
router.post('/publishTravelOften', function (req, res) {
if(req.user == null || req.user == undefined){
res.status(403).send(Error.ERROR_NO_USER);
}
else {
var time = Date.now();
var userLanguage = Geo.getCountry(req);
console.log("LOAD TIME /publishTravelOften: " + (Date.now() - time));
Config.setCountry(Geo.getCountry(req));
publishTravelOften(req, function (error, data) {
if (!error) {
data.lang = Lang.getLang(userLanguage);
data.socketUrl = Config.getSocketUrl();
data.apiUrl = Config.getApiUrlWeb();
res.send(data);
}
else {
res.status(500).send(error);
}
});
}
});
function publishTravelOften(req,callback){
console.log("########");
console.log(req.body);
console.log("########");
var url = Config.getApiUrlWeb() + "travel/often/create?user="+req.user._id+"¤cy="+Geo.getCountry(req);
var options = {
url: url,
form:req.body,
headers: {
'apikey': Config.getAPIKeyWeb()
},
};
request.post(options, function (error, response, body) {
var parsedResponse = JSON.parse(body);
if (parsedResponse.success == false)
callback(parsedResponse, parsedResponse);
else {
var data = {
newTravel: parsedResponse.data
};
callback(error, data);
}
});
}
my problem is that when i print the data i get on the nodejs part, i have this
{ from: 'ChIJO_PkYRozGQ0R0DaQ5L3rAAQ',
to: 'ChIJ9xUaAY73vEcRUt8vzFOSk1w',
'datesStart[]': [ '1471683240000', '1471596840000' ],
'datesEnd[]': [ '1471683240000', '1471596840000' ],
price: '134.93',
places: '[]',
package: 'medium',
transport: 'airplane',
pickupRange: '15',
dropRange: '5' }
the number arrays get converted to string arrays, also the field names change from datesStart and datesEnd to 'datesStart[]' and 'datesEnd[]'
is this normal? and how can i prevent the arrays from change from number to string arrays?