Null values with OR condition inside jsx expression is not working - javascript

I have a piece of code that is supposed to render a component, or a placeholder div.
I've placed this inside the return block of another component, but I can't figure out why the placeholder div never renders.
Here is the piece of code in the return block mentioned:
{renderBannerSummary() || <div className={spacer} />}
renderBannerSummary is a function that renders a component that sometimes returns null.
I can see that null is indeed being returned on occasion via the console
I can also see that if I extract the logical OR statement entirely, and log it out, it logs the div whenever renderBannerSummary returns null, as expected:
So, my question is, why is it that the spacer div is never shown in the UI when renderBannerSummary returns null/is falsy?
Instead, nothing renders at all.
Any help appreciated, thanks

This should work for you:
{ renderBannerSummary() ? renderBannerSummary():<div className={spacer} /> }
This code will render <div className={spacer}/> if renderBannerSummary() is null, undefined or false

Apparently my conditional OR expression will never return the right hand side, as curly braces {} within the render part of a component will always trigger the code, meaning that my method call will always trigger, thus always being true - within the {}, my code was not conditional

There's nothing wrong with your or condition ||, but it all depends on your function that might return null
so you've the condition(inside jsx expression)
{ mightReturnNull() || <div>spacer</div> }
if mightReturnNull is written like this
function mightReturnNull(){
return null;
}
it will always render the spacer
but if mightReturnNull is written like this
function mightReturnNull(){
return <>{null}</>;
}
it basically returns a fragment element(or any wrapper element of your choice) and that's of course not a null and those it's not a falsy value, that's why you'll end up rendering the left-hand side, because it's a truthy value

Related

Using react JSX and HTML in a ternary operation and cannot get it to display it correctly

the variable twitter_username resolves to either a username or null.
{{twitter_username}?<p>#{twitter_username}</p>:null}
I want this to display #username if there is a username or nothing at all if the value is null.
If there is a username it displays fine but if the return is null I get an
# instead of nothing.
{{twitter_username}?<p>{twitter_username}</p>:null}
this code returns the username if there is a username and is blank when there is none.
a nice and easy way to do it { twitter_username && (<p>#{twitter_username}</p>) }
Here the left part of the ternary operator will continue to the right only if the first part (twitter_username) if defined. The right part is a return statement who returns jsx

getBody always returns null in Apps Script even though that's how I think it should be written

My code is intended to make editing easier in Google Docs, but doesn't quite work and returns getBody null. I've already tested setting "body" as a variable, but that doesn't quite work. Due to how inexperienced I am with Javascript, it's hard to wrap my head around why exactly getBody returns null. So, it'd help me for the future if you knew where I'm going wrong with this.
function myFunction() {
var searchResult
searchResult =
DocumentApp.getActiveDocument().getBody().findText("very",searchResult)
Logger.log(searchResult)
while (searchResult !== null)searchResult.getElement().asText().setAttributes(searchResult.getStartOffset(),searchResult.getEndOffsetInclusive(),"#FF000")
searchResult =
DocumentApp.getActiveDocument().getBody().findText("very",searchResult)
}
function highlightProblem() {
var words = ["very","so","totally","really"]
words.forEach(findText)
}
function onOpen(){
DocumentApp.getUi().createMenu('everythingisnotfine.avi').addItem('Higlight Words That Make You Sound Like a Dandy', 'higlightProblem').addToUi()
}
Your body is not null. Your first problem is in this line
searchResult = DocumentApp.getActiveDocument().getBody().findText("very", searchResult)
you have findText("very", searchResult) while you do not have the variable searchResult. As per documentation this requires a range class (read here)
Next up is the whole mess here
while (searchResult !== null)
searchResult.getElement().asText()
.setAttributes(searchResult.getStartOffset(),
searchResult.getEndOffsetInclusive(),
"#FF000"
)
I did some formatting to better see the whole while loop. First of all, this is an endless loop, because it will keep repeating as searchResult is never changed inside of the loop so this step is either skipped or will continue endlessly. Next up is this particular method:
.setAttributes(searchResult.getStartOffset(),
searchResult.getEndOffsetInclusive(),
"#FF000"
)
Please read up on the method here as you are using it incorrectly. You are providing a string to the method, where it expects an object. In the same documentation page scroll down to the next method, without the offsets, it shows an example of how attributes should be formatted.
Next we move outside of the loops. This seems to be pointless
searchResult = DocumentApp.getActiveDocument().getBody().findText("very",searchResult);
perhaps you meant it to be done inside the while loop? Because essentialy what you are currently doing is
Set searchResult from document.
Log searchResult object
Set searchResult attributes (since that looks like hex color code, I assume you wish to color the code). Do this while searchResult is not null.
Set searchResult from document
End
If this was meant to be inside the while loop then you need to add { after while and } after the last action you wish to happen in 1 iteration of the while loop.

React inline conditional component attribute

I've been searching everywhere and can't find an answer to my question. So I want a conditional attribute which is only displayed on certain conditions, example:
<Button {this.state.view === 'default' && 'active'}></Button>
As you can see I only want to indicate the button active if the this.state.view is equal to default. However, I get Unexpected token, error...
But when I try to put an attribute before it, for example:
<Button isActive={this.state.view === 'default' && 'active'}></Button>
It passes the syntax error and displays fine but this is not what I wanted to achieve.
How can I fix this? And what could be the reason behind it not passing?
UPDATE
So I just found out that in react-bootstrap the property active is a shorthand of active=true so I solved it using
<Button active={this.state.view === 'default'}></Button>
So In case, someone encounters this problem I'm leaving it here. However, I still want to know why the conditional attribute is failing without enclosing it inside a prop-like syntax, example:
This:
active={this.state.view === 'default'}
Versus
{this.state.view === 'default' && 'active'}
First of all, JSX is just a syntactic sugar for React.createElement. So, it may look like, but, in reality, you don't specify html attributes: in fact, you are always passing props.
For instance, the JSX code <input type="button" value="My button" /> is transpiled into React.createElement('input',{type:'button',value:'My Button'}). And, when necessary, React engine renders this React Element to the DOM as a HTML element.
That said, we have that JSX transpiles a prop without a value as true (check docs). For instance: <Button active></Button> is transpiled to React.createElement(Button, { active: true });.
But, we know that HTML5 specification does not accept attribute=true (as pointed here). For instance: <button disabled=true></button> is invalid. The correct is <button disabled></button>.
So, to render the HTML element to the DOM, React considers only props that are valid attributes (if not, the attribute is not rendered). Check all supported html attributes. And, then, finally, if it's a boolean attribute, it removes the true/false value, rendering it properly.
For instance: <button active={true}></button> is transpiled to React.createElement("button", { active: true }); and then React renders to the DOM <button></button>, because there is no active attribute in HTML specification for the <button/> tag (is not in the supported attributes list).
But <button disabled={true}></button> is transpiled to React.createElement("button", { disabled: true }); and React renders to the DOM <button disabled></button>.
I just said that to clarify your case.
You're trying to pass an active prop to the Button component (first letter uppercase means that's a React component: there is a React Component called Button handled somewhere in your code).
That means:
<Button active></Button> is transpiled to React.createElement(Button, { active: true });
and
<Button active={true}></Button> is transpiled to React.createElement(Button, { active: true });
The same thing!
So, if you want to do a conditional prop, you can simply do something like that:
<Button active={this.state.view === 'default'}></Button>
You have a condition inside brackets. Means that, if your this.state.view is equal to default (true), active prop will be passwed down to the component with the true value. If not equal, with the false value.
Button Component, then, must someway handle this active prop. It can render the button element and, for instance, change it's style, pass the disabled prop... I created a fiddle to demonstrate this: https://jsfiddle.net/mrlew/5rsx40gu/
Actually, I guess it is a duplicated question that I answered it in this link sometimes ago. for this specific post, there is no need condition prop for a boolean value, because it works well like below:
const { booleanValue } = this.props;
return (
<input checked={booleanValue} />
);
Or make your own boolean value:
const booleanValue = someThing === someOtherThing;
return (
<input checked={booleanValue} />
);
Both of them work well, because when the booleanValue is false, react doesn't see the active prop, hence it does not exist, unless you pass checked prop to a specific component that the component will receive false checked prop from this.props.
But, if you wanna a have a prop on your specific component with a condition and if the condition returns false you don't want it there are two ways, I like second:
First:
<Component someProp={condition ? yourValue : undefined} />
Second:
<Component {...(condition && { someProp: yourValue })} />
In JSX, component properties (or props) compile to a plain JavaScript object. Prop names are used as the keys of the object, and prop values are stored under those keys. The first example from the JSX docs does a great good job demonstrating this. In your case {view === 'default' && true} is a raw value without an associated prop name. Without a prop name to use as a key (specified by the syntax name=), JSX has nowhere to put that value in the final props object.
However, JSX will accept props via your original syntax if the expression inside the curly braces evaluates to an object. For example, you could do {{ active: view === "default" }}. In this case JSX can get both the key and value that it needs from the provided object, so no active= is necessary.

Is there a way to change variable values while debugging JavaScript?

I have a breakpoint on this piece of code (using Firebug):
if (validator.formValidate([dom.forumid]))
How can I skip this validation part and get into the if clause even if my dom.forumid is not valid, i.e. the call to formValidate() returns false? So how can I make it return true?
I was thinking about modifying the JavaScript, but I don't know how that's done.
As of today (Chrome 67) you can just double-click any variable on the right hand side under the "Scope" section and edit it in real-time.
In Firebug I do this by entering an assignment into the watch input field
to assign a new value
to assign a new function that returns the value I expect
This also works in Chrome ~33 (just tested) execpt: one has to enter the assignment into the console (which actually works in Firefox too, but using the watch panel is faster :).
In Firebug, you have to edit and re-save the assignment typed into the input on each break.
Of course, replacing the function will prevent the code from functioning normally on further runs. To avoid this one might save the original value to window._savedFnX or so and then do the assingment again assigning the saved function/value. But I think this is a workaround from saving one stepping through the code again and again to reach the point of interest. I often realize that there's a bad condition and then I want to continue (while the code would not) to test the rest of the code.
Take a look at these screenshots:
Code background
In the screenshot photo is an instance with this code:
{
...
_loaded: false, // set to true on some condition
...
isLoaded: function(){
return this._loaded;
},
...
}
The method isLoaded() will be replaced in the example to always return true. :)
Firebug
(Applies to Firebug ~1.12)
Stop at breakpoint
Go to the console
Assign function that returns the value you want to the variable in scope (or being reachable) [ORANGE]
The [BLUE] box highlights the the value that would be returned by isLoaded() and the value that is being returned by the replaced function.
Chrome
(Applies to Chrome ~34.0)
Note: in Chrome you can also edit the source code and re-run the modified version.
Stop at breakpoint
Go to the console
Assign function that returns the value you want to the variable in scope (or being reachable) [ORANGE]
(Refresh to see the result) [GREEN]
The [BLUE] box highlights the the value that would be returned by isLoaded() and the value that is being returned by the replaced function.

Jquery if div doesn't exist

I'm using 1 js for 2 different pages. 1 page doesn't have a div which the other does. So when I submit the values, I get a $( js error
for
$('.description'+save_id+'').html(description_val).show(); //update category description
I suspect that I get the error because there is nothing to show(). Is there a short code I can use to detect if the div.description exists otherwise don't do the function?
jQuery will not error if it has nothing to perform on. The show() would not be a problem. To answer your question, though, you can check the length property on the jQuery object returned from $.
If the description_val variable is undefined, then the code will fail.
Try using an if() statement to only run the code if description_val is not undefined.
if(description_val) {
$('.description'+save_id+'').html(description_val).show();
}
Or if for some reason the value of description_val may be a value that would equate to false, then do this:
if(description_val !== undefined) {
$('.description'+save_id+'').html(description_val).show();
}
From what you posted I'd check to make sure the variables you're using are all defined at this stage. To check for existence you can do this:
if ($('.description' + save_id).size() > 0) {
// code here that operates on the div.
}
This is essentially just a syntactic alternative to checking the length property.

Categories

Resources