React : how to prevent escaping in data-attribute - javascript

I have a JSON that looks like this { "id":"xyz", "height":1024, "width":1024 } which I would like to have in a data attribute like :
<div data-command='{"id":"xyz","height":1024,"width":1024}'></div>
but when I use react it escapes the string as shown below :
<div data-command='{"id":"xyz","height":1024,"width":1024}'></div>
I use this code to generate the element
React.createElement("div",
{ "data-command" : JSON.stringify({ "id":"xyz", "height":1024, "width":1024 }), null)
does anyone know how I can get the JSON without the " escaping?
If it's not possible how can I transform it back in javascript so I can use JSON.parse after?

The 'dangerouslySetInnerHTML' attribute is precisely used for scenarios like this.
createMarkup() {
return {__html: `<div data-command='{"id":"xyz","height":1024,"width":1024}'></div>`};
}
render() {
return (
<div dangerouslySetInnerHTML={this.createMarkup()}>
</div>
);
}

Related

Split API to use its part as a variable

I am using an API that has a lot of different possible calls. I want to change a part of it in VUE so that depending on a different button different call is made.
https://api.themoviedb.org/3/movie/top_rated?api_key=<>&language=en-US&page=1
https://api.themoviedb.org/3/movie/upcoming?api_key=<>&language=en-US&page=1
Here are two different API calls that are possible and I want to make it so that it looks something like this:
"https://api.themoviedb.org/3/movie/" +variable+ "?api_key=<>&language=en-US&page=1"
and then depending on which button I pressed it would either make a call for "top_rated" or if another button is pressed it would be "upcoming"
You can use String literal ` ` to insert dynamic value.
<button #click="apiCall(true)">Upcoming</button>
<button #click="apiCall(false)">Top Rated</button>
...
methods: {
apiCall(isUpcoming) {
const apiType = isUpcoming ? 'upcoming' : 'top_rated';
const url = `https://api.themoviedb.org/3/movie/${apiType}?api_key=<>&language=en-US&page=1`;
// Fetch data with url.
...
}
}
There are many ways to archive this. Without the rest of the code I cannot suggest much.
Eventually you can create a method in your VUE component that returns the "top_rated" or "upconmig".
<template>
<button :href="'https://api.themoviedb.org/3/movie/' + getAction + '/?yourqueryparams'"></button>
</template>
<script>
export default {
name: 'Movie DB',
methods: {
getAction: function(){
return "top_rated"; //put condition here
}
}
}
</script>
I am not sure I understand your question, but maybe you need this:
vue template:
<button #click=handler('top_rated')>this is button no.1</button>
<button #click=handler('upcoming')>this is button no.2</button>
javascript:
methods: {
handler(type) {
const url = "https://api.themoviedb.org/3/movie/" + type + "?api_key=<>&language=en-US&page=1"
return fetch(url)
}
}

React inline logic in render()

I just wonder how apply inline templates logic in React.
I mean in case when I need change class of element how to do that easily?
class RegisterForm extends Component {
...
render() {
let email = this.state.email.error; //true or false
return (<div {email ? className="has-error" : className="regular"}></div>)
}
Then I have an error:
Syntax error: C:/project/components/signup/index.js: Unexpected token, expected ... (107:22)
How to perform that?
Or it's only possible to wrap in if/else full div block only?
You could do a couple things:
<div className={email ? "has-error" : "regular"}> </div>
Or to keep it cleaner
let email = this.state.email.error;
let divClass = email ? "has-error" : "regular";
return <div className={divClass}> </div>
Assign the value conditionally not attribute. Define className attribute and assign its value on the basis of email value.
Write it like this:
<div className = { email ? "has-error" : "regular"}> </div>

JSX with a HTML tag from a variable

I have a React component defined in JSX which returns a cell using either td or th, e.g.:
if(myType === 'header') {
return (
<th {...myProps}>
<div className="some-class">some content</div>
</th>
);
}
return (
<td {...myProps}>
<div className="some-class">some content</div>
</td>
);
Would it be possible to write the JSX in such a way that the HTML tag is taken from a variable? Like:
let myTag = myType === "header" ? 'th' : 'td';
return (
<{myTag} {...myProps}>
<div className="some-class">some content</div>
</{myTag}>
);
The above code returns an error:
"unexpected token" pointing at {.
I am using Webpack with the Babel plugin to compile JSX.
Try setting your component state and rendering like so:
render: function() {
return(
<this.state.tagName {...myProps}>
<div className="some-class">some content</div>
</this.state.tagName>
);
},
You can do something like:
const content = <div> some content </div>
return (
{myType === 'header'
? <th>{content}</th>
: <td>{content}</td>
}
)
Note that this does not really solve your question about "dynamic tag" but rather the problem you seem to have.
The first answer did not work for my case so I solved it in another way.
From React documentation each element converts to pure JS like this.
So it is possible to create elements for React component that are dynamic like this:
let myTag = myType === "header" ? 'th' : 'td';
React.createElement(
myTag,
{className: 'some-class'},
<div className="some-class">some content</div>
)

Have both JSX and normal className together

I have a css style class that needs to be in JSX form as it depends on the state, but I also need to use style class the ordinary way for styling. How do I combine these together?
I've tried
<span className={statusColor} className="uppercase">
Which only takes into account the last class one
<span className={statusColor uppercase}>
Which obviously looks for a variable called uppercase and errors out
<span className="uppercase {statusColor}">
Neither of them work
Below is a dummied-down version of my code. What is the correct way to do this?
const Component = React.createClass({
return {
completed: false
}
},
render () {
let statusColor;
this.state.completed === true ? statusColor = "green" : statusColor = "red";
return (
<div className="status-banner">
<span className="kata-text-status">Status: <span className={statusColor} className="uppercase">{this.state.completed.toString()}</span></span>
</div>
)
}
})
Try this:
<span className={`uppercase ${statusColor}`}>
This will use an ES6 template string (`uppercase ${statusColor}`) and interpolate statusColor with ${...}.
<span className={'uppercase' + ' ' + statusColor}>
You can do it in several ways.
Firstly you can use + to concat more than one string variables and generate dynamic strings
<span className={"uppercase " + statusColor}>
Or you can use npm modules classnames.
The brackets {} translate to normal JS. So you can just use + to concatenate.
<span className={"uppercase " + statusColor}>

PolymerJS POST JSON formatting

I am trying to POST using PolymerJS ajax-forms and I encounter a weird JSON format error. Can someone tell me why the quotes are missing around the keys? The only workaround I can think of is manually constructing the body with the quotes around the keys.
Code Snippet :
How I receive the values (rest are the same with the ids changed):
<div>
<paper-input label="Title" id="course-title" floatingLabel value="{{item.title}}"></paper-input>
</div>
<access-core-ajax
auto = "false"
url="domain/courses"
response="{{response}}"
method="post"
id="postCourse"
contentType="application/json"
headers='{"Accept": "application/json", "Content-Type":"application/json"}',
body = "{{item}}">
<template id="get-response-template" repeat="{{item in response.entries}}">
<p>Errors</p>
</template>
</access-core-ajax>
Polymer('create-new-course-page',{
domReady: function() {
console.log("Log: create-new-courses-page - Looks like we are domReady");
},
created: function() {
console.log("Item initialized");
this.item = {};
this.data={};
},
createNewCourse: function(event) {
console.log("HERE IS BODY", this.item);
this.$.postCourse.go();
}
And the JSON is see on the log:
{
title: "WRU",
// rest of key & values, where the keys are without the ""
}
You need to turn the body into a JSON string first. JSON.stringify can help.
...
createNewCourse: function(e) {
this.$.postCourse.body = JSON.stringify(this.item);
this.$.postCourse.go();
}
You may need to remove the body attribute here. You can also remove that auto attribute since by default it is false.

Categories

Resources