The title might not be the best way to describe the problem, but I was wondering if there was a better practice to declaring an object in getDefaultProps?
In my render method I call several keys from from a prop/state that get updated on a click event i.e. this.props.player.name. The problem is that on page load this.props.player is blank and calling .name errors out. I know I can do something like ...
getDefaultProps: function() {
return {
player: {
name: null,
team: null
position: null
}
};
}
but it doesn't feel right. I was hoping there might be something similar to how Ruby does .try() where it won't try to call a method on a undefined prop.
The problem is specifically that this.props.player is undefined, if you define an empty object it will prevent the error from occurring. It's not bad practice to stub out the keys you're anticipating, but setting the default value to {} will be enough to prevent it from throwing.
You can create your data from ImmutableJS. Then you can get any part of your data like this:
this.state.getIn(['player', 'name', ...])
or
this.state.get('player')
This will not throw error even player is not defined or other, it will return undefined (or null) I don't remember
The update and updateIn work the same
see the doc here
I'd like to add this vanilla JS solution too - var x = (user || {}).name;
Source
Related
I'm trying to implement an AVA Unit Test for my mixpanel implementation. To do this, I'm comparing the result of mixpanel.track() where if it returns anything, the track was successful, otherwise, it should be undefined.
I thought maybe it was that it was using a different mixpanel instance so I tried creating a named instance and ensuring that but it was to no avail. I'm also trying the same process but with Amplitude and it seems to be working fine (when I am opted out, the response fails as expected)
I have done this in my components where if
const test = mixpanel.track('event_name', {}) is successful, !!test === true but if I do mixpanel.opt_out.tracking() prior to const test = mixpanel.track('event_name', {}), then !!test === undefined.
Expected behaviour (and the observed behaviour when I use it in my components):
trackResponse === undefined
Observed behaviour:
trackResponse === { event: 'asdf',
properties:
{ '$browser': 'Safari',
'$current_url': 'about:blank',
'$browser_version': null,
'$screen_height': 0,
'$screen_width': 0,
mp_lib: 'web',
'$lib_version': '2.30.1',
time: 1572898982.142,
distinct_id: '[some_id]',
'$device_id': '[some_id]',
'$initial_referrer': '$direct',
'$initial_referring_domain': '$direct',
token: '[token]' } }
where [some_id] and [token] are some distinct values I've deleted.
I don't understand why in the AVA test, I'm receiving a response when normally a failed track() results in an undefined response. Could someone shine some light on this?
Let me know if I need to provide any additional information. Thanks.
I figured it out in case anyone else runs into this issue.
I used a debugger to step into the mixpanel.track() calls and figured out that to see if the user had opted out, mixpanel checks for a property in the localStorage and compares it to see if it's === to '0'. If this fails, it assumes the user has not opted out and carries out the track call as normal.
I guess during the AVA test, it was unable to access this property and assumed the user had not opted out. To fix it, in my call to mixpanel.init(), I added opt_out_tracking_persistence_type: 'cookie' as an option so that my opt_out call was being saved somewhere that the property could be accessed during the test.
I am trying to test a method where one of the thing that it does it lock orientation of screen. Jasmine however is throwing error in the line:
(<any>window).screen.orientation.lock('portrait') saying that undefined is not a constructer.
I even tried not using typescript types and just window.screen.msOrientationLock('landscape') and other window.screen methods but I get same error. I have the _$window_ injected in beforeEach of my tests too.
Testing if it locks is not necessary part of my test so is there some way to skip this specific line or correct this error. Thanks :)
Well it was easy. I had to inject window object and assign it to a global variable in my global beforeEach like this:
$window = _$window_;
Then, the next issue was that the property orientation was not available in the window.screen object unfortunately. I just had to mock it inside my spec like this:
$window.screen.orientation = {
lock: function() { return; }
};
Just had to do this before spying/calling the method which had window.screen.orientation.lock method inside it.
You have a json object.
By mistake you pass some element (property1) to a function and the value passed doesn't exists...
myFunction (json.propety1); // it must be 'property1' , with r
I'd like to set any configure element to say the browser "I can't pass undefined json properties, rise an error"
I think this is not possible, is't it ?
Thanks in advance
in myfunction you can check for undefined and then do something
like
function myFunction(jsonproperty){
if(jsonproperty === undefined){
//do something with the DOM to pass whatever you wanna say in the browser
}
}
Is that what you were trying to do? You could also throw an exception like this:
throw "json property was undefined"
but you would only see that in some kind of js debugger console. Nowadays all browser have one. Usually accessible with "F12"
I'm trying to troubleshoot a page with lots of JS, including ads, and something is causing window.console to be replaced which suppresses the typical console logging output that I would want to see.
Is there a way to identify which JS is overwriting window.console? Maybe trigger a breakpoint only when typeof(window.console) is modified?
Great question! And I think I can help.
Use Object.defineProperty https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
to recreacte .log property.
Smth like this:
Object.defineProperty(console, "log", {
set: function () { throw 'Hoh!' }
});
console.log = 'abc';
I asked a question yesterday, but I've kept going with it. Instead of calling next() and passing an an Error object, I worked out what it was doing, and tried to copy it. Now, when someone logs in and it fails, I do this:
res.render("pages/home",
{
flash:{"danger":["Login failed. Please enter your details and try again."]},
body:{},
section:"home",
locals : { userId : req.body.email }
}
This does exactly the same thing as the old code. I step through it, and I can see that the locals object contains a property called userId, with the value I expect. In the Jade template, I have this:
p it's #{typeof(userId)}
if(typeof(userId) != 'undefined')
p Welcome #{userId}
input(type='text', name='email', id="inputEmail", placeholder="Email", value="#{userId}")
else
input(type='text', name='email', id="inputEmail", placeholder="Email", value="")
This always renders as 'it's undefined' and then an empty text box. I have read several questions on this, and as far as I can see, they all say the same thing: if I set locals to be a JSON object, I can access it's properties by this syntax, but it does not work.
What am I doing wrong ?
You might first need to better understand how locals object actually work.
On the server-side, doing this:
res.render('view', { property: 'value' } );
would make property available in your views like so:
div Value = #{property}
You can also do the following to have the same effect:
res.locals.property = 'value';
res.render('views');
Note the usage of locals object. More info
Coming back to your issue, since you have
res.render("pages/home", { locals: { userId : req.body.email } })
to access userId in this case you would do:
p Welcome #{locals.userId}
So I'm guess you're confusing the two approaches ending up using locals object the wrong way.
OK - turns out that 'locals' doesn't mean anything any more. Leaving my code as it is, I needed to access 'locals.userId', but I could have just set the value of 'userId' and not had the 'locals' object at all.