How to fix array to string error with wysiwyg editor - laravel

So im trying to update a comment on my database using a "PUT" method in react
this is my function to fetch the api :
updateComment = () =>{
const comments = this.state.updateComment;
const i = this.state.selectedTicket.id;
fetch(apiurl + "/Comment/" + i +"/update", {
method: 'PUT',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
comments:comments,
})
})
.then((response) => response.json())
.then((responseJson) => {
if (responseJson.status === "SUCCESS") {
alert("Successfully updated comment")
} else {
alert("Could not update comment.")
}
})
}
this is my function to track the change in the editor
changeUpdateComment(event) {
this.setState({updateComment: event});
}
and this is where i have the input for the editor
<button onClick={this.showEditor}>comment</button>
{this.state.showEditor && (
<Editor
editorState={this.state.updateComment}
toolbarClassName="toolbarClassName"
wrapperClassName="wrapperClassName"
editorClassName="editorClassName"
onEditorStateChange={this.changeUpdateComment}
/>
)}
<button onClick={this.updateComment}>comment</button>
I keep on getting an Error exception of "Array to String" when trying to update the comment, any solutions?

Related

Do a HTTP Post in Cypress without using a test

I have a Cypress test:
describe('Create a session ', () => {
it('creates a session', () => {
cy.request({
method: 'POST',
url: `${Cypress.env('apiURL')}/api/v1/user/login/`,
form: true,
body: {
email: Cypress.env('email'),
password: Cypress.env('password'),
},
}).then((response) => {
expect(response.status).to.eq(200);
cy.task('setKey', response.body.data.key);
});
});
});
This POST returns some session data needed to create a dummy account:
describe('Create a company ', () => {
it('creates a company', () => {
cy.task('getKey')
.then((data: Key) => {
key = data;
})
.then(() => {
createNonce();
cy.request({
method: 'POST',
url: `${Cypress.env('apiURL')}/api/v1/cli/`,
headers: {
'X-Auth-Timestamp': epochTime(),
'X-Auth-Key': key.key,
'X-Auth-Nonce': nonce,
'X-Auth-Signature': createSignature(),
},
body: {
args: ['seeder', 'create', 'abc1'],
},
}).then((response) => {
expect(response.status).to.eq(200);
// TODO: we need some REST endpoints to return a JSON object instead of a string
data = JSON.parse(response.body.substring(response.body.indexOf('{')));
cy.task('setCompany', data);
});
});
});
});
I'm not sure I need these functions to be tests since they don't test anything, but just do a POST request. Is it possible to maybe move the functionality into a cypress task?
You can add the post request in your commands file:
function postRequest() {
cy.request({
method: 'POST',
url: `${Cypress.env('apiURL')}/api/v1/cli/`,
headers: {
'X-Auth-Timestamp': epochTime(),
'X-Auth-Key': key.key,
'X-Auth-Nonce': nonce,
'X-Auth-Signature': createSignature(),
},
body: {
args: ['seeder', 'create', 'abc1'],
},
})
}
Cypress.Commands.add('postRequest', postRequest)
An assuming all the rest of your code is fine, and you want only to abstract the logic; then in your test you can invoke that command:
describe('Create a company ', () => {
it('creates a company', () => {
cy.task('getKey')
.then((data: Key) => {
key = data;
})
.then(() => {
createNonce();
cy.postRequest().then((response) => {
expect(response.status).to.eq(200);
data = JSON.parse(response.body.substring(response.body.indexOf('{')));
cy.task('setCompany', data);
});
});
});
});
You can move these into before() or beforeEach() so they will be separate from your tests.
describe('Create a company ', () => {
before(() => {
cy.task('getKey')
.then((data: Key) => {
key = data;
})
.then(() => {
createNonce();
cy.request({
method: 'POST',
url: `${Cypress.env('apiURL')}/api/v1/cli/`,
headers: {
'X-Auth-Timestamp': epochTime(),
'X-Auth-Key': key.key,
'X-Auth-Nonce': nonce,
'X-Auth-Signature': createSignature(),
},
body: {
args: ['seeder', 'create', 'abc1'],
},
}).then((response) => {
expect(response.status).to.eq(200);
// TODO: we need some REST endpoints to return a JSON object instead of a string
data = JSON.parse(response.body.substring(response.body.indexOf('{')));
cy.task('setCompany', data);
});
});
})
it('creates a company', () => {
//test code
});
});

I am having trouble integrating my twilio video api through react hooks, specifically for the videochat.js

webpage; videochat.js; room.js
const handleSubmit = useCallback(async event => {
event.preventDefault();
alert('Work');
const data = await fetch('./video/token', {
method: 'POST',
body: JSON.stringify({
identity: username,
// room: roomName
}),
headers: {
'Content-Type': 'application/json'
}
}).then(res => res.json());
setToken(data.token);
}, [username, roomName]);
This is the part where I am likely having an issue (lines 18-32 of videochat.js)

Updating array afte doing a post request

it's my first time working with Vue and I'm trying to make a simple crud using Spring as backend. My problem is that when I send the actor with the post request, and I try to make a get request to get the new actors list, it doesn't get updated until I refresh the page.
This is part of the html that I want to display. Just a form and the list of actors that I bring from my DB.
<v-flex>
<v-text-field
v-model="newActor.firstName"
label="Nombre"
prepend-icon="person"
></v-text-field>
</v-flex>
<v-flex>
<v-text-field class="ml-5"
v-model="newActor.lastName"
label="Apellido"
> </v-text-field>
</v-flex>
<v-flex>
<v-btn :class="['white--text','green']" #click="addActor">Enviar</v-btn>
</v-flex>
<li v-for="actor in actors" v-bind:key="actor.id" :class="['mt-5']">
id = {{actor.actorId}}
<br>
name = {{actor.firstName}}
<br>
apellido = {{actor.lastName}}
<br>
lastUpdate = {{actor.lastUpdate}}
</li>
This is my vue script.
export default {
data() {
return {
alert: false,
alertMessage: '',
alertType: 'success',
urlBase: 'http://localhost:8081/',
newActor:
{
firstName: '',
lastName: '',
lastUpdate: ''
},
background: 'yellow',
actors: []
}
},
methods:
{
getActors: function()
{
this.actors = []
let self = this
fetch(this.urlBase+'actors/all')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
for (var variable of myJson) {
self.actors.push(variable);
}
});
},
addActor: function()
{
if (this.newActor.firstName != '' && this.newActor.lastName != '')
{
let self = this
fetch(this.urlBase+'actors/add', {
method: 'POST',
body: JSON.stringify(this.newActor),
headers:{
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));
this.alert = true;
this.alertMessage = "Usuario agregado con éxito";
this.getActors(); //Here is where I tried to get the actors again.
console.log(this.actors);
}
else
{
this.alert = true;
this.alertType = 'error';
this.alertMessage = "Usuario no registrado";
}
}
},
created: function()
{
this.getActors()
}
}
It is because this.getActors(); is called before the fetch method is done. That's the way javascript works.
You can try putting this.getActors(); in the then.
Example :
if (this.newActor.firstName != '' && this.newActor.lastName != '')
{
let self = this
fetch(this.urlBase+'actors/add', {
method: 'POST',
body: JSON.stringify(this.newActor),
headers:{
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.catch(error => console.error('Error:', error))
.then(response => {
console.log('Success:', response);
this.alert = true;
this.alertMessage = "Usuario agregado con éxito";
this.getActors(); //Here is where I tried to get the actors again.
console.log(this.actors);
})
}

CKEditor Upload Adapter Sends [object Promise] to Server

I have been trying to implement CKEditor5 into a vuejs project and after getting all the infrastructure working, I cannot get the actual file to upload to a php server. The code calls the server and if I return a success message and file url, it all works correctly. Here is my code:
<template>
...
<ckeditor :editor="editor" v-model="details.SystemText" :config="editorConfig"></ckeditor>
...
</template>
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
class UploadAdapter {
constructor(loader) {
this.loader = loader;
}
upload() {
return new Promise((resolve, reject) => {
const data = new FormData();
data.append('upload', this.loader.file);
axios({
url: '/index/uploadimage',
method: 'post',
data,
headers: {
'Content-Type': 'multipart/form-data;'
},
withCredentials: false
}).then(response => {
if (response.data.result == 'success') {
resolve({
default: response.data.url
});
} else {
reject(response.data.message);
}
}).catch(response => {
reject ( 'Upload failed');
});
});
}
abort() {
}
}
export default {
data () {
details: {},
editor: ClassicEditor,
editorConfig: {
extraPlugins: [ this.MyCustomUploadAdapterPlugin ],
}
},
methods: {
MyCustomUploadAdapterPlugin ( editor ) {
editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
return new UploadAdapter( loader );
};
},
}
Clicking the image icon in the toolbar will show the file select dialogue correctly, and upon file selection will submit a post to the server. However, the binary file is not sent, but simply:
Form Data
------WebKitFormBoundaryqPGA20WRKz9VvADd
Content-Disposition: form-data; name="upload"
[object Promise]
I have spent two days looking at all other plugins like CKFinder and others, and I seem to always get the same content being sent to the server. The line
data.append('upload', this.loader.file);
does not seem to append the actual file which is what I think it should do.
My value of this.loader is
loader.file
Promise {<pending>}
__proto__: Promise
catch: ƒ catch()
constructor: ƒ Promise()
finally: ƒ finally()
then: ƒ then()
Symbol(Symbol.toStringTag): "Promise"
__proto__: Object
[[PromiseStatus]]: "pending"
[[PromiseValue]]: undefined
Tried using their cloudservice but point to my own urls and that got the upload working.
editorConfig: {
cloudServices: {
tokenUrl: '/index/tokenendpoint',
uploadUrl: '/index/uploadimage'
}
}
I was also able to remove all the upload adapter code.
Thank you
Reason for your problem is that in version 11.0.0 of ckeditor5-upload plugin the API was changed, loader.file is now a Promise (see release notes). Unfortunately the docs were not updated accordingly.
You need to adjust your upload function a little:
upload() {
return this.loader.file
.then( uploadedFile => {
return new Promise( ( resolve, reject ) => {
const data = new FormData();
data.append( 'upload', uploadedFile );
axios( {
url: '/index/uploadimage',
method: 'post',
data,
headers: {
'Content-Type': 'multipart/form-data;'
},
withCredentials: false
} ).then( response => {
if ( response.data.result == 'success' ) {
resolve( {
default: response.data.url
} );
} else {
reject( response.data.message );
}
} ).catch( response => {
reject( 'Upload failed' );
} );
} );
} );
}
The docs that had this issue are now fixed and use promise properly. Hope this solves the problem for you!
Use jQuery ajax. I cannot find an equivalent using fetch or axios. The key is setting contentType: false and processData: false.
upload() {
return new Promise((resolve, reject) => {
const data = new FormData();
data.append('postedFile', this.loader.file);
$.ajax({
url: '/index/uploadimage',
data,
contentType: false,
processData: false,
type: 'POST',
success: response => {
resolve({
default: response.data.url
});
},
error: () => {
reject('Upload failed');
}
});
});
}
They are working on it, it is a bug.
https://github.com/ckeditor/ckeditor5/issues/1618

File upload with fetch API vuejs returns 419 unknown status

I am using VUE.js with Laravel to upload file using fetch api. I have added the csrf token to the header of the request, but still getting the 419 unknown status. Any help will be appreciated thanks.
Here is the JS of the component
<script>
export default {
name:'UploadModal',
data(){
return {
image:'',
ext:'',
file:''
};
},
methods: {
onFileChange(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.file = files[0];
this.createImage(files[0]);
},
uploadArtwork: function () {
let formData = new FormData();
formData.append('artwork', this.file);
fetch(this.$parent.itemUrl, {
method:'POST',
body: formData,
headers: {
'Content-Type': 'multipart/form-data',
'X-CSRF-TOKEN' : Laravel.csrfToken
}
})
.then(res => res.json())
.then(res => {
alert(res);
})
.catch(e => console.log(e));
},
createImage(file) {
var image = new Image();
var reader = new FileReader();
var vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
},
}
}
</script>
I know this is an old question, but I ran into this issue as well when using fetch and the linked answer (Laravel 5.5 ajax call 419 (unknown status)) did not help, since that relates to jQuery's Ajax method.
For those who are facing the same issue, it looks like this is due to the default credentials setting (defaults to "omit"), which essentially omits the csrf header for some reason. You can get around this by changing credentials to "same-origin" or "include" depending on your needs.
Example:
fetch("/leads", {
method: 'POST',
credentials: "same-origin",
headers: csrf_header
}).then(res => res.json())
.then(
(json) => {
this.setState({
isLoaded: true,
items: json.leads.data,
sort: json.sort,
search: json.search,
sort_by: json.sort_by,
filter: json.filter
});
}
);

Resources