simple website contact submit code using fetch sending formdata to api.
the fetch method returns'Failed to execute 'fetch' on 'Window': Invalid name' error in console, meanwhile XMLHttpRequest works.
How can i fix the fetch method?
contactForm.addEventListener('submit', async function (e) {
e.preventDefault();
// console.log('clicked');
const formData = {
name: formName.value,
email: formEmail.value,
tel: formTel.value,
message: formMessage.value,
};
// FIXME
try {
const response = await fetch('/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData),
});
return response.json();
} catch (err) {
console.log(err.message);
}
// XMLHttp methode works
// let xhr = new XMLHttpRequest();
// xhr.open('POST', '/');
// xhr.setRequestHeader('Content-Type', 'application/json');
// xhr.onload = function () {
// if (xhr.responseText === 'success') {
// //add a popout window
// formName.value = '';
// formEmail.value = '';
// formTel.value = '';
// message.value = '';
// } else {
// alert('Something went wrong!');
// }
// };
// xhr.send(JSON.stringify(formData));
});
Related
I try to set up plugin ckeditor/ckeditor5-export-pdf on my Laravel App But I cant do this. I still get issues like: Uncaught TypeError: Failed to resolve module specifier "#ckeditor/ckeditor5-export-pdf/src/exportpdf". Relative references must start with either "/", "./", or "../".
I did all steps as in docs: https://ckeditor.com/docs/ckeditor5/latest/features/export-pdf.html#configuration But when I try use import ExportPdf from '#ckeditor/ckeditor5-export-pdf/src/exportpdf'; I get the error like above. Please help. Maybe some have stuck on this issue before
import ExportPdf from '#ckeditor/ckeditor5-export-pdf/src/exportpdf';
console.log(ExportPdf);
$(document).ready(function () {
/*function ExportPdf(editor) {
editor.execute('exportPdf');
}*/
function SimpleUploadAdapter(editor) {
editor.plugins.get('FileRepository').createUploadAdapter = function(loader) {
return {
upload: function() {
return loader.file
.then(function (file) {
return new Promise(function(resolve, reject) {
// Init request
var xhr = new XMLHttpRequest();
xhr.open('POST', '/admin/instructions/ckmedia', true);
xhr.setRequestHeader('x-csrf-token', window._token);
xhr.setRequestHeader('Accept', 'application/json');
xhr.responseType = 'json';
// Init listeners
var genericErrorText = `Couldn't upload file: ${ file.name }.`;
xhr.addEventListener('error', function() { reject(genericErrorText) });
xhr.addEventListener('abort', function() { reject() });
xhr.addEventListener('load', function() {
var response = xhr.response;
if (!response || xhr.status !== 201) {
return reject(response && response.message ? `${genericErrorText}\n${xhr.status} ${response.message}` : `${genericErrorText}\n ${xhr.status} ${xhr.statusText}`);
}
$('form').append('<input type="hidden" name="ck-media[]" value="' + response.id + '">');
resolve({ default: response.url });
});
if (xhr.upload) {
xhr.upload.addEventListener('progress', function(e) {
if (e.lengthComputable) {
loader.uploadTotal = e.total;
loader.uploaded = e.loaded;
}
});
}
// Send request
var data = new FormData();
data.append('upload', file);
data.append('crud_id', {{ $instruction->id ?? 0 }});
xhr.send(data);
});
})
}
};
}
}
var allEditors = document.querySelectorAll('.ckeditor');
for (var i = 0; i < allEditors.length; ++i) {
ClassicEditor.create(
allEditors[i], {
extraPlugins: [SimpleUploadAdapter, /*ExportPdf*/],
/*toolbar: [
'exportPdf', '|',
],
exportPdf: {
stylesheets: [
'./path/to/fonts.css',
'EDITOR_STYLES',
'./path/to/style.css'
],
fileName: 'my-file.pdf',
converterOptions: {
format: 'A4',
margin_top: '20mm',
margin_bottom: '20mm',
margin_right: '12mm',
margin_left: '12mm',
page_orientation: 'portrait'
}
}*/
}
);
}
});
</script>```
I solved my problem with https://ckeditor.com/ckeditor-5/online-builder/ Builded what I want and setup it on my App
I've created a POST XMLHttpRequest with FormData successfully. I now need to capture it's response body and get it stored in a JSON file.
Cypress.Commands.add(
"Post_Clients",
(imagePath, imageType, attr1, attr2, attr1Val, done) => {
cy.fixture(imagePath, "binary").then(imageBin => {
Cypress.Blob.binaryStringToBlob(imageBin, imageType).then(blob => {
const xhr = new XMLHttpRequest();
xhr.withCredentials = true;
const data = new FormData();
data.set(attr1, attr1Val);
data.set(attr2, blob);
xhr.open("POST", "https://api.teamapp.myhelpling.com/admin/clients");
xhr.responseType = "json"
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("access-token", accesstoken);
xhr.setRequestHeader("client", client);
xhr.setRequestHeader("expiry", expiry);
xhr.setRequestHeader("token-type", tokentype);
xhr.setRequestHeader("uid", uid);
xhr.onload = function() {
done(xhr);
};
xhr.onerror = function() {
done(xhr);
};
xhr.send(data);
});
});
}
);
it.only("API POSTing TEST", () => {
cy.Post_Clients(
"/images/clients/Golden JPEG.jpeg",
"image/jpeg",
"client[name]",
"client[client_logo_attributes][content]",
"Test Attr 1 Value is Hi!!!",
resp => {
cy.writeFile(
"cypress/fixtures/POST API OUTPUT DATA/Client.json",
resp.response
);
expect(response.status).to.eq(201);
}
);
});
Kindly note that expect(response.status).to.eq(201); assertion works well.
Following code logs the body properly in the console
cy.log("Response Body", resp.response);
console.log("Response Body", resp.response);
Response Body is: -
{"client":{"id":452,"name":"Test Attr 1 Value is Hi!!!","client_logo":{"id":543,"path":"https://api.teamapp.myhelpling.com/uploads/client_images/6279486665-1551780183.","thumb":"https://api.teamapp.myhelpling.com/uploads/client_images/thumb_6279486665-1551780183.","medium":"https://api.teamapp.myhelpling.com/uploads/client_images/medium_6279486665-1551780183.","large":"https://api.teamapp.myhelpling.com/uploads/client_images/medium_6279486665-1551780183.","filename":"blob","ratio":1.78}}}
but
cy.writeFile(
"cypress/fixtures/POST API OUTPUT DATA/Client.json",resp.response
);
doesn't save the response body in Client.JSON file.
cy.writeFile seems to not work in this code. I've verified this by
passing a JSON e.g. {"A":"B"} and that too didn't make it to the
JSON.
Thanks everyone for all you kind help. I've made it work by calling cy.writeFile inside onLoad event before triggering XHR request. Here's the code sample with some other updates that I've made for my other works: -
Cypress.Commands.add(
"Post_Bucket",
(imagePath, imageType, title, img, titleVal) => {
cy.fixture(imagePath, "binary").then(imageBin => {
Cypress.Blob.binaryStringToBlob(imageBin, imageType).then(blob => {
const xhr = new XMLHttpRequest();
const data = new FormData();
data.set(title, titleVal);
data.set(img, blob);
cy.readFile(Cypress.env("IDStore")).then(obj => {
xhr.open(
"POST",
Cypress.env("BucketPostURLPart1") +
obj.journeyID +
Cypress.env("BucketPostURLPart2"),
false
);
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("access-token", accesstoken);
xhr.setRequestHeader("client", client);
xhr.setRequestHeader("expiry", expiry);
xhr.setRequestHeader("token-type", tokentype);
xhr.setRequestHeader("uid", uid);
xhr.onload = function() {
if (this.status === 201) {
cy.writeFile(
Cypress.env("BucketOutputFile"),
JSON.parse(this.responseText)
);
cy.readFile(Cypress.env("IDStore")).then(obj => {
obj.bucketID = JSON.parse(this.responseText).bucket.id;
cy.writeFile(Cypress.env("IDStore"), obj);
});
}
};
xhr.send(data);
});
});
});
}
);
This is the simple example try with this one.
cy.request('https://jsonplaceholder.cypress.io/users')
.then((response) => {
cy.writeFile('cypress/fixtures/users.json', response.body)
})
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'm trying to make an AJAX request to one of my routes which should return some data, but I can't solve the fact that when I make an AJAX request I'm being redirected to the route I'm requesting.
How can I prevent this from happening?
Ajax:
var request = new XMLHttpRequest();
var url = 'http://localhost:3000/signin';
var credentials = {
email: document.getElementsByName('email')[0].value,
password: document.getElementsByName('password')[0].value
};
JSON.stringify(credentials);
request.onreadystatechange = function() {
if (request.readyState == XMLHttpRequest.DONE) {
if(request.status == 200) {
if(request.readyState == 4) {
var data = JSON.parse(request.responseText);
console.log(data);
}
} else if(request.status == 400) {
console.log('There was an error 400');
} else {
console.log('something else other than 200 was returned');
}
}
}
request.open('POST', url, true);
request.setRequestHeader('Accept', 'application/json');
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.send(credentials);
Api Endpoint:
app.post('/signin', function(req, res) {
request.post({
url:'http://localhost:3000/api/authenticate',
form: {
email: req.body.email,
hashed_password: req.body.password
},
}, function(err, httpResponse, body) {
console.log(req.xhr);
console.log(req.headers);
if (err) {
return console.error('failed:', err);
}
console.log('successful! ', JSON.parse(body));
//user.token = data.token;
res.json(JSON.parse(body));
});
});
Looking at the Flux Documentation I can't figure out how the code to a ajax update, and a ajax fetch would fit into the dispatcher, store, component architecture.
Can anyone provide a simple, dummy example, of how an entity of data would be fetched from the server AFTER page load, and how this entity would be pushed to the server at a later date. How would the "complete" or "error" status of request be translated and treated by the views/components? How would a store wait for the ajax request to wait? :-?
Is this what you are looking for?
http://facebook.github.io/react/tips/initial-ajax.html
you can also implement a fetch in the store in order to manage the information.
Here is an example (it is a concept, not actually working code):
'use strict';
var React = require('react');
var Constants = require('constants');
var merge = require('react/lib/merge'); //This must be replaced for assign
var EventEmitter = require('events').EventEmitter;
var Dispatcher = require('dispatcher');
var CHANGE_EVENT = "change";
var data = {};
var message = "";
function _fetch () {
message = "Fetching data";
$.ajax({
type: 'GET',
url: 'Url',
contentType: 'application/json',
success: function(data){
message = "";
MyStore.emitChange();
},
error: function(error){
message = error;
MyStore.emitChange();
}
});
};
function _post (myData) {
//Make post
$.ajax({
type: 'POST',
url: 'Url',
// post payload:
data: JSON.stringify(myData),
contentType: 'application/json',
success: function(data){
message = "";
MyStore.emitChange();
},
error: function(error){
message = "update failed";
MyStore.emitChange();
}
});
};
var MyStore = merge(EventEmitter.prototype, {
emitChange: function () {
this.emit(CHANGE_EVENT);
},
addChangeListener: function (callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function (callback) {
this.removeListener(CHANGE_EVENT, callback);
},
getData: function (){
if(!data){
_fetch();
}
return data;
},
getMessage: function (){
return message;
},
dispatcherIndex: Dispatcher.register( function(payload) {
var action = payload.action; // this is our action from handleViewAction
switch(action.actionType){
case Constants.UPDATE:
message = "updating...";
_post(payload.action.data);
break;
}
MyStore.emitChange();
return true;
})
});
module.exports = MyStore;
Then you need to subscribe your component to the store change events
var React = require('react');
var MyStore = require('my-store');
function getComments (){
return {
message: null,
data: MyStore.getData()
}
};
var AlbumComments = module.exports = React.createClass({
getInitialState: function() {
return getData();
},
componentWillMount: function(){
MyStore.addChangeListener(this._onChange);
},
componentWillUnmount: function(){
MyStore.removeChangeListener(this._onChange);
},
_onChange: function(){
var msg = MyStore.getMessage();
if (!message){
this.setState(getData());
} else {
this.setState({
message: msg,
data: null
});
}
},
render: function() {
console.log('render');
return (
<div>
{ this.state.message }
{this.state.data.map(function(item){
return <div>{ item }</div>
})}
</div>
);
}
});
I hope it is clear enough.