Using React and trying to print a value exactly from {this.state.value} - reactjs

I'm using React.js and in my state object of my App component, I have a value that contains \n characters and spaces.
this.state = {
value: "def foo():\n print('this is a function')\n\nfoo()"
}
However, when I try to show this value to the screen by wrapping this.state.value in a p tag like <p>{this.state.value}</p>, it simply prints out
def foo(): print('this is a function') foo()
without showing the spaces and \n characters. Is there any way I can get the value to print out exactly like how it's shown in the state object? Going into the React inspector on Chrome confirms that the value indeed matches the one in my state object.

This isn't specific to React but to how white space characters are treated in HTML. A new line can be displayed as <br> inside <p> and multiple spaces can be displayed as . While newline character and multiple spaces are displayed similarly to single space character.
It could be outputted as
<p>def foo():
print('this is a function')
foo()</p>
with same result.
In order to change that, the way how white space is displayed should be changed with white-space CSS property, e.g.:
<p style={{ 'white-space': 'pre' }}>
{this.state.value}
</p>
If the intention is to output the code with specified indentation and monospaced font, there's already <pre> tag that already has appropriate style by default, it can be used instead of <p>.

try to use string template with back-tick syntax like:
this.state = {
value: `def foo():
print('this is a function')
foo()`
}
EDIT: for better readability you can try to define constant before setState call:
const strTemplate = `def foo():
print('this is a function')
foo()`;
this.state = {
value: strTemplate
}
Let me know if it works :)

Try out this string:
this.state = {
value: "def foo():<br/> print('this is a function')<br/><br/>foo()"
}

Related

angular 10 in html template array variable don't match type declaration

I am using a global variable and type defined as:
global.ts
export type ReservationCurrentPC = Array<{StartDateTime: string, EndDateTime: string, Who: string}>;
export class GlobalVariables {
public static ReservationsCurrentPC: ReservationCurrentPC = [];
}
then imported it in component .ts
import { GlobalVariables , ReservationCurrentPC } from '../GlobalVariables';
then did a getter at component.ts for using it in its html template.
get GetReservationsMyPC(): ReservationCurrentPC { return GlobalVariables.ReservationsCurrentPC; };
then it executes a single push as:
case 'RSV':
// stemp[i].Param1 = PCNameID.
// stemp[i].Param2 = StartDate.
// stemp[i].Param3 = EndDate.
// stemp[i].Param4 = ReserveByAccountName.
GlobalVariables.ReservationsCurrentPC.push (stemp[i].Param2, stemp[i].Param3, stemp[i].Param4);
and then try to use it in the html template.
<div *ngFor="let b of GetReservationsMyPC">
<li>
Desde [{{b.StartDateTime}}] hasta [{{b.EndDateTime}}] reservado para: {{b.Who}}
</li>
<button (click)="RemReserve(b.StartDateTime)">Remover esta reserva</button>
</div>
the problem is, the html loops 3 times with the variable 'b' , and it is not recognizing the type structure, like 3 fields per item, and like b.StartDateTime , b.EndDateTime, b.Who returns nothing, only if print just 'b' variable it will get the 3 strings pushed, as if it were a single plain array.
How to handle that structured variable properly at html template? I saw several examples but, using local-component variable, and that works, but I need to use this global variable because it is required to be filled from another component (which handled a map view where the user clicks, and the object clicked in the map triggers several events, and that is where is requested info from the API about the object clicked, and as response it returns the data for the push), so, it must be a global variable as it is handled in several components.
fixed:
GlobalVariables.ReservationsCurrentPC.push ({StartDateTime: stemp[i].Param2, EndDateTime: stemp[i].Param3, Who: stemp[i].Param4 });
What an adventure for me!.

Convert string to a jsx string in react | How to convert Unicode escape sequences to Unicode characters in react

<Hello name={'\u4ed8\u52a0\u4fa1\u5024\u7a0e# IE9834481A'}></Hello>
class Hello extends Component {
render() {
return (
<div>
{this.props.name}
</div>
);
}
}
The above 2 code snippets are working fine & giving the result as expected, i.e, the escape sequences are getting converted to the relevant unicode characters.
Now consider, there is an array(dynamically populated) and the array values will be the default value for the input tag & this array contains unicode escape sequences.
Ex: <input value={array[i]}></input>
I have tried doing <input value={<Hello name={array[i]}></Hello>}></input>
But the o/p is [object Object].
If I hardcode the string in input tag, o/p is as expected
<input value={<Hello name={'\u4ed8\u52a0\u4fa1\u5024\u7a0e'}></Hello>}></input>
How should I solve this issue, ultimately I want to pre-populate input tag with array value containing unicode escape sequences (after converting to unicode characters).
console.log(JSON.parse('"\u4ed8\u52a0\u4fa1\u5024\u7a0e# IE9834481A"'));
It is not allowed to pass a React Node to the input value. Here is a string expected. If you need the Hi use a function.
const hello = (name) => `Hi ${name}`;
ReactDOM.render(
<input value={hello('\u4ed8\u52a0\u4fa1\u5024\u7a0e')}></input>,
document.getElementById('root')
);

How to put comma separator in input field in reactjs?

i have a form where i show previous field value in input tag. But, as i put type=number. then my .toLocaleString("en-IN") would'nt work.Also, i want to show comma in INR currency styles. i.e 12,25,789
Following is my code:
<Col lg="2">
<Form.Control
size="sm"
// type="number"
value={temp.originalAmount.toLocaleString("en-IN")}
onChange={this.handlechangevalue.bind(
this,
item,
keys,
index
)}
/>
</Col>
P.S been using react-bootstrap
It's not clear for me where you want to use the comma separated values but you can change between styles with the help of regexp and replace. Something like this:
// 1234567 => 12,34,567
const encode = string => string.match(/(\d{2})(\d{2})(\d{3})/).slice(1).join(',');
// 12,34,567 => 1234567
const decode = string => string.replace(/,/g, '');
(If your input is looks like two digits / comma / two digits / comma / three digits but this can be changed easly ofc.)
Then you can convert the result to number before save into the state and the back to the comma version to display the user.
Also, I would use a text type on the input field an a regexp based validator.
I'm using similar in case of dates.
I've come across this before. What you can do is restrict the type of input in your handlechangevalue function to numbers only. If any other character appears then discard/ignore it.
Something like this:
handlechangevalue(e) {
if( parseInt(e.target.value) !== NaN ) {
this.setState({val: e.target.value});
}
}

ng-bind with AngularJS translate interpolation

I need to render characters such as < and >, which may be included in a user's first or last name. I'm using angular translate to render the name, passing the first and last name as values. However, if the first or last name contains < the value will not be displayed. I think I need to use something like ng-bind="translation_key | translate | values" but this is incorrect. How can I use ng-bind with angular translate interpolation? Is this the correct way to go about rendering a translated value that contains chars such as <, >? Thanks.
*Edit
This almost works but the sanitizer outputs an error.
ng-bind="'locales.user_filter' | translate: { first: user.firstName, last: user.lastName }"
Error: [$sanitize:badparse] The sanitizer was unable to parse the following block of html:
I wound up using a filter before passing the values to the translation key.
.filter('htmlEntities', function () {
return function (input) {
return String(input).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
};
});
var first = $filter('htmlEntities')(scope.user.firstName);
var last = $filter('htmlEntities')(scope.user.lastName);
scope.displayName = $translate.instant('locales.user_filter', { first: first, last: last });
<td ng-bind-html="displayName"></td>

ExtJs: TextArea how to return value as an array instead of as a string?

On ExtJs 6.2, I have a form with a TextArea.
When user inputs text on several lines, for example :
line 1
line 2
The binded value is currently a string :
value= "line 1↵line 2"
But I need to send value (to server) as an array, when the store is submitting.
How to tell to the textarea to return input text as an array ?
value : ["line1", "line2"]
without to have to split string as array on the server-side.
Edit: I dont't want just to split value. Because I would to update the default behavior of the textarea to avoid to have to apply the split (in ViewController) each time that I using it.
I have created a fiddle with how I would approach it (assuming I have understood your requirements correctly!)
https://fiddle.sencha.com/#view/editor&fiddle/1uq7
This example turns an array into a string when coming into the textarea, and splits it on the way out.
Ext.define('ArrayTextArea', {
extend: 'Ext.form.field.TextArea',
alias: 'widget.arraytextarea',
setValue: function(val){
// if it's an array then join with a newline
if(Ext.isArray(val)){
val = val.join('\n');
}
return this.callParent([val]);
},
getValue: function(){
var val = this.callParent(arguments);
// split the value by newline char
return val.split('\n');
}
});
document.getElementById('textarea').value.split('↵')
You can use standard way provided by sencha http://docs.sencha.com/extjs/5.0.0/api/Ext.form.field.TextArea.html#placeholder-simple-getValue
Check this and reply.

Resources