How to render Draft-js text in React from server - reactjs

I using Draft-js to build my text-editor.
What I want to do is on clicking the submit button, the submitted text should appear on right side (as you can see, the blank side)
I'm calling a handleSubmit function to post the content to server:
handleSubmit = e => {
e.preventDefault();
const query = JSON.stringify(convertToRaw(this.state.editorState.getCurrentContent()));
const payload = {
query:query
}
axios({
url:'http://localhost:9000/queries',
method:'POST',
data: payload
})
}
and to retrieve the content :
getQueries(){
axios.get("http://localhost:9000/queries")
.then(response => {
const data = response.data;
this.setState({queries:data});
})
}
I'm bit confused, on how to use convertFromRaw to convert the content to the desired text.
Where should I call the method ?
Thanks in advance

You have to understand that DraftJS is a library that converts whatever you have inside the editor into it own format.
For Example, apple is converted to,
{
"blocks": [{
"key": "f6b3g",
"text": "apple",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [{
"offset": 0,
"length": 5,
"style": "ITALIC"
}],
"entityRanges": [],
"data": {}
}],
"entityMap": {}
}
Yep, it's that big. So, in order to convert it back from this format to apple you need a component which knows how to interpret it. You cannot just use a div tag. In this case, it's the editor component itself!
So you can do the following to display the content in readonly mode.
<Editor readOnly={true}
editorState={EditorState.createWithContent(this.state.editorState.getCurrentContent())}/>
Now, say if you want to send the editor contents to an API so that you can save it in DB and then get the content from the API and display it.
Convert from Editor Format to JSON
const requestBody = JSON.stringify(convertToRaw(this.state.editorState.getCurrentContent()))
Post JSON to your API
fetch(url, {
method: 'POST',
body: requestBody
});
Get JSON from your API
const response = await fetch(url, {
method: 'GET'
});
Convert from JSON to Editor format and display using Editor (You can remove readonly if you want the user to edit the contents)
<Editor readOnly={true}
editorState={EditorState.createWithContent(convertFromRaw(JSON.parse(response))}/>

Related

React API call, render data with QuickBase's new RESTful API

I'm trying to figure out what i'm doing wrong here... I've been out of coding for awhile and trying to jump back in for an external application utilizing QuickBase's RESTful API. I'm simply trying to get data from QuickBase to be used outside in an external app to create charts/graphs.
I'm not able to use GET as it gives me only the field names and no data, if I use POST, then I get the values of these fields as well. I'm able to get all the data rendered in the console, but am struggling to get each field rendered to be used in the app.
let headers = {
'QB-Realm-Hostname': 'XXXXXXXXXXXXX.quickbase.com',
'User-Agent': 'FileService_Integration_V2.1',
'Authorization': 'QB-USER-TOKEN XXXXXX_XXXXX_XXXXXXXXXXXXXXXX',
'Content-Type': 'application/json'
}
let body = {"from":"bpz99ram7","select":[3,6,80,81,82,83,86,84,88,89,90,91,92,93,94,95,96,97,98,99,101,103,104,105,106,107,109,111,113,115,120,123,224,225,226,227,228,229,230,231,477,479,480,481],"sortBy":[{"fieldId":6,"order":"ASC"}],"groupBy":[{"fieldId":40,"grouping":"equal-values"}],"options":{"skip":0,"top":0,"compareWithAppLocalTime":false}}
fetch('https://api.quickbase.com/v1/records/query',
{
method: 'POST',
headers: headers,
body: JSON.stringify(body)
})
.then(res => {
if (res.ok) {
return res.json().then(res => console.log(res));
}
return res.json().then(resBody => Promise.reject({status: res.status, ...resBody}));
})
.catch(err => console.log(err))
Hoping to get some help getting the data rendered to be used in React, as well as any tips from anyone who's used QuickBase's new API calls in their realm! And I apologize if it's an easy question/issue, haven't been in React for a couple years... and I'm feeling it!
Thanks!
A successful response from Quickbase for this call has a property data which is an array of the records returned. Each element of this array is an object where the FID for each field returned is a key for nested object - or objects for some field types - with the field's value. Here's a very contrived example:
{
"data": [
{
"1": {
"value": "2020-10-24T23:22:39Z"
},
"2": {
"value": "2020-10-24T23:22:39Z"
},
"3": {
"value": 2643415
}
}
],
"fields": [
{
"id": 1,
"label": "Date Created",
"type": "timestamp"
},
{
"id": 2,
"label": "Date Modified",
"type": "timestamp"
},
{
"id": 3,
"label": "Record ID#",
"type": "recordid"
}
]
}
If you put the data array of the response directly into state with const [quickbaseData, setQuickbaseData] = useState(res.data); for example, you need to keep the structure of the response in mind when accessing that data. If I want to get the value of FID 3 from the first record in the response I would need to use quickbaseData[0]["3"].value. For most field types value will be a string or integer but for some field types it will be an object. You can see the way values are returned for each field type in Field type details.
Depending on your needs you might consider processing the Quickbase response into a new, simpler array/object to use in your application. This is especially helpful if the value being returned needs additional processing such as converting into a Date() object. This would also allow you to make your application API agnostic since other than initially processing the response from Quickbase the rest of your application doesn't have to have any knowledge of how Quickbase returns queried data.
On the Quickbase side of things, there isn't the equivalent of 'SELECT *' so to get data for all fields of a table where you don't know the schema (or it changes frequently) you can run a GET on the Fields endpoint: https://developer.quickbase.com/operation/getFields an then use the field IDs in the response to make the POST call to /records/query

Get the image from the server

I uploaded an image file using axios post method and it was successfully uploaded to the server...
On return to the POST method, it returned the Image URL as:
{imageUrl: "/root/TTAppJava/images/players/Screenshot from 2020-11-24 16-38-57.png"}
Now, I want to display the image onto my screen.
How can I get that image?
I am using React.js to implement this.
The URL I used to post the image is:
http://139.59.16.180:8269/player/details/${id}
I am doing this to upload my data:
var formData = new FormData()
formData.append("file", image);
const theWrapper = {
"data": {
"name": name,
"age": age,
"email": email,
"gender": gender
}
}
formData.append("theWrapper", JSON.stringify(theWrapper))
Axios.post("http://139.59.16.180:8269/player/add",
formData,
{ headers: { Authorization: "Bearer " + localStorage.getItem("token") } }
).then(res => {
console.log(res)
alert("Player added successfully.")
history.push("/players")
})
.catch(err => alert(err.messge))
And the response I am getting is:
{id: 14, name: "shreyas", email: "asdfjka#gmail.com", gender: "Male", imageUrl: "/root/TTAppJava/images/players/Screenshot from 2020-11-24 16-38-57.png", …}
I will give you an example how its done in Node app, since the underlying concept will be the same as I am not a Java developer.
First please note your image_url/download_url should be saved as follows,
https://yourdomain/folder/image_name
example: http://localhost:3000/uploads_folder/my_image_name.jpg
and then you need a route in Java Spring which figures out what image to send to the front-end as Stream like below,
router.get("/:folder/:image_name", async (req, res) => {
const { folder, image_name } = req.params;
// find an image based on the downloadUrl in the folder where files are saved.
// Please note, after uploading file successfully generate a download url
// appropriately so that this route can help figure out which image you
// are looking for.
const file = path.join(`path/to/${folder}`, `${image_name}`);
// Figure out a way how stream works in your context.
// Providing MIME type is important!
const type = mime[path.extname(file).slice(1)] || "image/jpg";
const s = fs.createReadStream(file);
s.on("open", () => {
res.set("Content-Type", type);
s.pipe(res);
});
s.on("error", (err) => {
// Handle Error
});
});

Passing through an array with axios

I am having an issue passing through an array through axios post call. The issue is that on the api endpoint the data received is null, when I try posting using postman it works fine so the endpoint is working. Example of the array
I need to pass the data in this format:
{
"UpdateItemList": [
{
"Text": 1,
"Value": "5"
},
{
"Text": 1,
"Value": "5"
}
]
}
Code:
export function createLogEntry(postData) {
let payload = {
UpdateItemList: postData
};
const request = axios.post('https://localhost:44312/api/Audit/AddLogEntry', {
data: payload
});
return {
type: CREATE_LOG,
payload: request
}
}
Is there any issue with the way I am passing through the data with my current code?
Try with
const request = axios.post('https://localhost:44312/api/Audit/AddLogEntry',payload);
This worked for me!
The issue is that you are confusing two ways axios can be used. Currently you are actually posting your data nested in an object within and the key data:
{
data: {
UpdateItemList: postData
}
}
If you are using the axios.post function, you should just pass your object with the data to post as the second object like this:
const request = axios.post('https://localhost:44312/api/Audit/AddLogEntry', payload);
If you are using the config object method, you should just pass one single object with url, method and data as keys.
// Send a POST request
axios({
method: 'post',
url: 'https://localhost:44312/api/Audit/AddLogEntry',
data: payload
});
This behaviour is explained in the axios Readme here: https://github.com/axios/axios#axios-api

Can't get the data response object from react-native-customized-image-picker

I have read in the document here: https://github.com/mg365/react-native-customized-image-picker that I could get the response object of data from an image, but when I tried it I got undefined. I can get other objects like size, mime, and path like this:
SelectPhoto = () =>{
ImagePicker.openPicker({
cropping: true,
title: 'Select a Picture',
isCamera: true,
}).then((imgResponse) => {
console.log(imgResponse[0].path); <-- This logs the correct path
console.log(imgResponse[0].data); <-- This logs the undefined
let imgSource = { uri: imgResponse[0].path };
this.setState({
userimgSource: imgSource,
});
});
}
My ultimate goal is to upload an image to a server and I think having the data is required? I am using the RNFetchBlob multipart/form-data. Any help on this is appreciated, thank you!
First of all data prop is not at all required, you can upload your file using path. If you really want data then there is a prop name "includeBase64"(by default it false) set it to true.
SelectPhoto = () =>{
ImagePicker.openPicker({
cropping: true,
title: 'Select a Picture',
isCamera: true,
includeBase64:true
})
NOTE: Setting {includeBase64: true} will convert your image to base64 which may lead to OUT OF MEMORY issue in android when you try to upload a large image.
To Upload Your using path and React-Native-Fetch-Blob
RNFetchBlob.fetch('POST', URL, {
// dropbox upload headers
...
'Content-Type': 'multipart/form-data',
// Change BASE64 encoded data to a file path with prefix `RNFetchBlob-file://`.
// Or simply wrap the file path with RNFetchBlob.wrap().
}, [
// element with property `filename` will be transformed into `file` in form data
{ name: 'file', filename: 'Image.png', data: RNFetchBlob.wrap(response.uri) },
// custom content type
]).then((res) => {
})
.catch((err) => {
// error handling ..
})
And if you have RN>=0.54 then You don't need fetch-blob to upload image React-native now has full blob support.try this
var photo = {
uri: URI,
type:image/png, // check your object you will get mime-type in image picker response.
name: file,
fileName:Image.png
};
var body = new FormData();
body.append('file', photo);
axios({
method: 'post',
url: 'URL',
data: body,
config: { headers: {'Content-Type': 'multipart/form-data' }}
})
reference Links
upload video using React-native-fetch-blob
react-native blob support announcement
send Form data using Axios

How to add additional request body values to Apollo GraphQL request?

I'm using Apollo with the Scaphold.io service and for writing blobs to that service I need to be able to add additional options to the request body.
The full Scaphold example can be found here: https://scaphold.io/docs/#uploading-files
But it does something like this:
form.append("variables", JSON.stringify({
"input": {
"name": "Mark Zuck Profile Picture",
"userId": "VXNlcjoxMA==",
"blobFieldName": "myBlobField"
}
}));
// The file's key matches the value of the field `blobFieldName` in the variables
form.append("myBlobField", fs.createReadStream('./mark-zuckerberg.jpg'));
fetch("https://us-west-2.api.scaphold.io/graphql/scaphold-graphql", {
method: 'POST',
body: form
}).then(function(res) {
return res.text();
}).then(function(body) {
console.log(body);
});
Where it adds a blobField to the request body.
Based on this, I need to pass into the variables a blobFieldName property, and then add to the request body the value passed to that property with the blob. However, using Apollo I can't add to the request body. I tried the following, but it's absent from the request body when I check in the network inspector:
export const withCreateCoverPhoto = graphql(CreateCoverPhoto, {
props: ({mutate}) => ({
createCoverPhoto: (name, file) => mutate({
variables: {
input: {
blobFieldName: name,
},
},
[name]: file
}),
}),
});
Please advise.
Thanks for the question. Currently the best way to upload files is by [appending it to FormData and sending it up to the server using fetch] (https://medium.com/#danielbuechele/file-uploads-with-graphql-and-apollo-5502bbf3941e). Basically, you won't be able to have caching here for the file itself, but this is the best way to handle uploading files on Scaphold using a multipart request.

Resources