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);
}
});
};
Related
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 have implemented this by following this tutorial and it's working perfectly. After successful authentication the image is uploading on my Google Drive perfectly. But now I want to know
how can I add parent's folder name directory (parent/folderOne/folderTwo) for my uploaded image?
And I also need the fileID for newly uploaded image.
In java script I can do that in
const fileMetadata = {
'name': 'any_file_name',
parents: ['1xxxXj_sdsdsdsd0Rw6qDf0jLukG6eEUl']
};
But here I don't have any knowledge on ajax, so any help would be highly appreciated.
Thanks!
This is the code for uploading to Google Drive:
$(document).ready(function() {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const redirect_uri = "http://localhost/googleDriveUpload/upload.html" // replace with your redirect_uri;
const client_secret = "***********"; // replace with your client secret
const scope = "https://www.googleapis.com/auth/drive";
var access_token= "";
var client_id = "********************"// replace it with your client id;
$.ajax({
type: 'POST',
url: "https://www.googleapis.com/oauth2/v4/token",
data: {code:code
,redirect_uri:redirect_uri,
client_secret:client_secret,
client_id:client_id,
scope:scope,
grant_type:"authorization_code"},
dataType: "json",
success: function(resultData) {
localStorage.setItem("accessToken",resultData.access_token);
localStorage.setItem("refreshToken",resultData.refreshToken);
localStorage.setItem("expires_in",resultData.expires_in);
window.history.pushState({}, document.title, "/GitLoginApp/" + "upload.html");
}
});
function stripQueryStringAndHashFromPath(url) {
return url.split("?")[0].split("#")[0];
}
var Upload = function (file) {
this.file = file;
};
Upload.prototype.getType = function() {
localStorage.setItem("type",this.file.type);
return this.file.type;
};
Upload.prototype.getSize = function() {
localStorage.setItem("size",this.file.size);
return this.file.size;
};
Upload.prototype.getName = function() {
return this.file.name;
};
Upload.prototype.doUpload = function () {
var that = this;
var formData = new FormData();
// add assoc key values, this will be posts values
formData.append("file", this.file, this.getName());
formData.append("upload_file", true);
$.ajax({
type: "POST",
beforeSend: function(request) {
request.setRequestHeader("Authorization", "Bearer" + " " + localStorage.getItem("accessToken"));
},
url: "https://www.googleapis.com/upload/drive/v2/files",
data:{
uploadType:"media"
},
xhr: function () {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
myXhr.upload.addEventListener('progress', that.progressHandling, false);
}
return myXhr;
},
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(error);
},
async: true,
data: formData,
cache: false,
contentType: false,
processData: false,
timeout: 60000
});
};
Upload.prototype.progressHandling = function (event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
var progress_bar_id = "#progress-wrp";
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
// update progressbars classes so it fits your code
$(progress_bar_id + " .progress-bar").css("width", +percent + "%");
$(progress_bar_id + " .status").text(percent + "%");
};
$("#upload").on("click", function (e) {
var file = $("#files")[0].files[0];
var upload = new Upload(file);
// maby check size or type here with upload.getSize() and upload.getType()
// execute upload
upload.doUpload();
});
});
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.
I want to get the image path after the execution of the uploadFiles function. This way, I will have the value assigned to self.ProjectImagePath. But it is not working, I think it executes right after the function call. Anyone can help ?
self.submitProject = function(file) {
console.log("Submit Project \n");
uploadFiles.apply(this, arguments);
console.log(self.ProjectImagePath); ///ERROR HERE!!!! (UNDEFINED)
var data = JSON.stringify({
name: self.ProjectName,
room: self.room,
managers: self.Managers,
members: self.ProjectMembers,
image: self.ProjectImagePath
});
//console.log(data);
$http.post('/rooms/' + self.room + '/project', data).success(function(data) {
//$window.location.href = "/";
});
}
function uploadFiles(file) {
file.upload = Upload.upload({
url: 'projectImages/upload',
data: {
file: file
}
});
file.upload.then(function(response) {
$timeout(function() {
file.result = response.data;
self.ProjectImagePath = file.result;
});
}, function(response) {
if (response.status > 0)
self.errorMsg = response.status + ': ' + response.data;
});
}
After execution, the image is uploaded to the server but I cant get its path.
Im using AngularJS
You were having issues with calling code before the promise (asynchronous action) was finished.
This should do what you need:
self.submitProject = function(file) {
console.log("Submit Project");
function handleSuccess(response) {
self.ProjectImagePath = file.result = response.data;
// Should work correctly.
console.log(self.ProjectImage);
var data = JSON.stringify({
name: self.ProjectName,
room: self.room,
managers: self.Managers,
members: self.ProjectMembers,
image: self.ProjectImagePath
});
$http.post('/rooms/' + self.room + '/project', data).success(function(data) {
//$window.location.href = "/";
});
}
function handleError(response) {
if (response.status > 0)
self.errorMsg = response.status + ': ' + response.data;
}
uploadFiles(file, handleSuccess, handleError);
};
function uploadFiles(file, successCallback, errorCallback) {
file.upload = Upload.upload({
url: 'projectImages/upload',
data: {
file: file
}
});
file.upload.then(successCallback, errorCallback);
}
I am tring to upload a file using angular $http method to node backend
I want to upload the form with additional form fields.
This is my code
var data = new FormData();
data.append('title', 'sometitle');
data.append('uploadedFile', $scope.uploadedFile);
FileService.upload(url, data, function(data, status) {
if(status===HTTP_OK) {
$scope.uploadSuccess = true;
$scope.showUploadProgressBar = false;
} else {
// error occured
console.log(data);
}
});
FileService
FileService.upload = function(url, data, callback) {
$http({
method : 'POST',
url : url,
data : data,
headers: {'Content-Type': undefined },
transformRequest: angular.identity
}).success(function(data, status) {
callback(data, callback);
}).error(function(data, status) {
callback(data, status);
});
};
I am using node multiparty module for file upload. I am receiving the file correctly. But the field value for title is undefined.
I don't know why title value is undefined
Node.js backend file upload handler
var form;
if(options.uploads.tempDir) {
form = new multiparty.Form({uploadDir : options.root + '/' + options.uploads.tempDir});
} else {
form = new multiparty.Form();
}
form.on('file', function(name, receivedFile) {
var tmpPath = receivedFile.path,
fileName = receivedFile.originalFilename,
targetDirectory = uploadDirectory + '/' + req.params.id,
targetPath = targetDirectory + '/' + fileName,
file = {
filePath : targetPath,
tempPath : tmpPath,
fileName : fileName,
size : receivedFile.size
};
fileUploadStatus.file = file;
// move file
fse.move(tmpPath, targetPath, function(err) {
if(err) {
console.log('Error moving file [ ' + targetPath + ' ] ' + JSON.stringify(err));
}
});
});
form.on('error', function(err) {
fileUploadStatus.err = err;
req.fileUploadStatus = fileUploadStatus;
next();
});
form.on('close', function() {
req.fileUploadStatus = fileUploadStatus;
next();
});
form.on('field', function(name, value) {
console.log('field called');
console.log(name);
console.log(value);
req.body = req.body || {};
req.body[name] = value;
});
// ignoring parts. Implement any other logic here
form.on('part', function(part) {
var out = new stream.Writable();
out._write = function (chunk, encoding, done) {
done(); // Don't do anything with the data
};
part.pipe(out);
});
// parsing form
form.parse(req);