JSX not returning expected HTML - reactjs

I have the following code in my React component's return statement:
return (
<div>
{
props.photos.length > 0 &&
<div>
{props.photos.map((photo) =>
<div>
<a target="_blank"
href="/api/game_theory/game-files/{this.props.profileId}/files/{photo.id}/{photo.downloadName}">
{photo.title}
</a>
</div>
)}
</div>
}
</div>
);
It renders without errors, however the anchor tag looks like this in the HTML:
<a target="_blank" href="/api/game_theory/game-files/{this.props.profileId}/files/{photo.id}/{photo.downloadName}">
ActualPhotoName.jpg
</a>
So photo.title is being written out correctly, but photo.id, photo.downloadName, and this.props.profileId are not.
I'm sure I'm doing something wrong and I'd appreciate any help. :)

You can't "double-interpret" javascript with brackets in JSX. Assuming your props are available to you, try using ES6 string interpolation:
href=`/api/game_theory/game-files/${this.props.profileId}/files/${photo.id}/${photo.downloadName}`>

Wrap the whole href inside { } and remove it from the props:
href={"/api/game_theory/game-files/" + this.props.profileId + "/files/" + photo.id + "/photo.downloadName"}

Related

FormattedHtmlMessage react-intl v4

After upgrading to react-intl#4, we are facing a problem with all formattedHtmlMessages which have been used as html tag.
<FormattedHTMLMessage id={`${page}.legalNotice`} />
We tried replacing by formattedMessage and tried values={{...}}
<FormattedMessage id={`${page}.legalNotice`} />
But first of all the html is not considered as html tags.
Also as we use dynamic translation with different and undefined number of 'href's or even different 'target's on tags(links) it does not seem to be the solution.
Our translations are something similar to this:
"myPage1.legalNotice" : "By clicking here I accept <a target="_self" title="my specific title" href='first_link.pdf'>LINK1</a>, and <a target="_blank" title="second_title" href='second_link'>LINK2</a> and <a target="_blank" href='third_link' title='third_title'>LINK3</a>."
"myPage2.legalNotice" : "Another Text .. <a target="_blank" href='another_link.pdf'>LINK2</a>."
Check the Migration guide.
https://formatjs.io/docs/react-intl/upgrade-guide-3x
You have to provide the description for all the tags you use inside the message.
<FormattedMessage
defaultMessage="To buy a shoe, <a>visit our website</a> and <cta>eat a shoe</cta>"
values={{
a: msg => (
<a class="external_link" target="_blank" href="https://www.shoe.com/">
{msg}
</a>
),
cta: msg => <strong class="important">{msg}</strong>,
}}
/>
Update: If you need to pass custom variables inside the variable
Assuming you have customHref or customTarget variables defined:
a: msg => (
<a class="external_link" target="${customTarget}" href="${customHref}">
{msg}
</a>
)
To keep it the old way you can use such hack:
let message = intl.formatMessage({ id });
if (values) {
Object.entries(values).forEach(([key, value]) => {
message = message.replace(`{${key}}`, value.toString());
});
}
return(
<span
dangerouslySetInnerHTML={{ __html: formattedMessage }}
/>
)

Why we use (null) while creating dropdown in react js?

if we have not put null then it gives parsing error.
render() {
return (
<div className="dropdown" style = {{background:"Red",width:"2000px"}} >
<div className="button" onClick={this.showDropdownMenu}> User Info</div>
{this.state.displayMenu ? (
<ul>
<li><a className="active" href="#Orders">Orders</a></li>
<li>Payment Details</li>
<li>Your Address</li>
<li>Profile</li>
<li>Activity</li>
<li>Setting</li>
<li>Log Out</li>
</ul>
):
(
null
)}
</div>
);
}
If you don't want to add null don't use ternary, you can do this:
render() {
return (
<div className="dropdown" style = {{background:"Red",width:"2000px"}} >
<div className="button" onClick={this.showDropdownMenu}> User Info</div>
{ this.state.displayMenu && (
<ul>
<li><a className="active" href="#Orders">Orders</a></li>
<li>Payment Details</li>
<li>Your Address</li>
<li>Profile</li>
<li>Activity</li>
<li>Setting</li>
<li>Log Out</li>
</ul>
)}
</div>
);
}
You should always return a value from an expression. Even if the value it's null. To avoid ternary operators when you have a boolean you could render like this
return condition && <JSX />
For the case that this.state.displayMenu is false, you return null to preventing a component from rendering. In your case it's explicitly set to null.
React docs: https://reactjs.org/docs/conditional-rendering.html#preventing-component-from-rendering
In rare cases you might want a component to hide itself even though it was rendered by another component. To do this return null instead of its render output.

React - Colon is being replaced

Can anyone explain, why the colon is being replaced in this case?
<div className="col-6 text-left">
{
hasHomepage &&
<a href={'http://' + this.props.productGroup.supplierWebsite} target="_blank">
{this.props.productGroup.supplierName}
</a>
}
{
!hasHomepage &&
this.props.productGroup.supplierName
}
</div>
When it's being rendered the result is:
Is this a known issue or do I miss something?
what you are seeing is the content of this.props.productGroup.supplierName the place where you are adding http:// won't show in the browser content

Getting the picture from my api to load reactjs

I have this as my render function and I'm trying to pass the "{this.state.poster}" through it so it will load what ever random film poster it has received from the api. the console.log will show as /q2Y2EuDSaNCH88ETlyiu8bZc5TT.jpg for example but when I try to add that to the image with {this.state.poster} it doesn't work and im not sure why.
render() {
console.log(this.state.poster);
return (
<div className="main">
<h1> Lets see what you got</h1>
<div name="title">
{this.state.title}
</div>
<div name="overview">
{this.state.overview}
</div>
<div name="poster_path">
<img src="https://image.tmdb.org/t/p/original/${this.state.poster}" alt="picture" />
</div>
<div name="vote_average">
Vote:{this.state.vote}
</div>
<button onClick={this.getFilm}>Get Random Movie</button>
</div>
);
}
}
export default App;
first the curly brace specifying a js expression then string interpolation :)
<img src={`https://image.tmdb.org/t/p/original/${this.state.poster}`} alt="picture" />
string interpolation only works inside js expressions ;).
The ${expression} syntax is meant to be used in template literals
What you want here is to concatenate the state with the beginning of the image url like this :
<img
src={'https://image.tmdb.org/t/p/original/' + this.state.poster}
alt="picture"
/>
or by using a method like
getImgUrl (image) {
return 'https://image.tmdb.org/t/p/original/' + image;
}
and using it with
<img
src={this.getImgUrl(this.state.poster)}
alt="picture"
/>
You say that console.log prints out /q2Y2EuDSaNCH88ETlyiu8bZc5TT.jpg.
There is a backslash as the first character.
That tells me that the src attribute's value will be https://image.tmdb.org/t/p/original//q2Y2EuDSaNCH88ETlyiu8bZc5TT.jpg.
Note, the // to the right of original.
Try removing the extra backslash like following:
https://image.tmdb.org/t/p/original${this.state.poster}

React anchor link delims not parsing data

I have a simple anchor / for loop:
<ul className="user-list">
{this.props.partymembers.map((user, i) => {
return (
<li key={i} className="membername">
{user.username}
</li>
)
})}
</ul>
But the link just shows up as /friends/add/{user.id} instead of /friends/add/141513531 am I missing something here? Thanks. Username shows fine, but not inside the ""
I managed to solve it by doing
<li key={i} className="membername">
{React.createElement('a', { href: '/friends/add'+user.id}, user.username)}
</li>
but that almost seems hacky, is there a better way to do it?
The whole attribute needs to be either a string or an expression. So something like this:
<a href={'/friends/add/' + user.id}>{user.username}</a>
If you're using babel to transpile ES6, you can use template strings:
<a href={`/friends/add/${user.id}`>{user.username}</a>

Resources