Trying to test whether element has attribute without directly assessing the element - javascript

Trying to create query object on clicks on various buttons by sending attributes on html called "attr-{{foo}}" which get their name from an ng-repeat or some other means. I wanted on controller that first tests if the element has all attributes that map onto the keys of the query object in the scope, and continue this if else chain down to having only one attribute; however, when I tried this, I would get the error "cannot find .value of 'null'", as I was testing with
(below you will find a snippet that is representative of my controller)
vm.openFoos = function (event) {
if (event.target.attributes.getNamedItem('attr-foo').value &&
!event.target.attributes.getNamedItem('attr-bar').value) {
var obj = {
foo: event.currentTarget.attributes.getNamedItem('attr-foo').value,
name: $routeParams.name
} else if {
(event.target.attributes.getNamedItem('attr-foo').value &&
event.target.attributes.getNamedItem('attr-bar').value) {
var obj = {
foo: event.currentTarget.attributes.getNamedItem('attr-foo').value,
name: $routeParams.name,
bar: event.currentTarget.attributes.getNamedItem('attr-bar').value
}
}
data.getReviews(obj)
.success(function (data){$log.debug(data)}).error(function(e){$log.debug(e)});
};
This works if I click on elements with both attr-foo and attr-bar (as by the convention of this testing from most strict case of having attributes to least, I know if I had written the if statements in reverse I would get the error "cannot find value of null". Sample HTML:
<span class="one" ng-click="vm.openFoos($event) attr-foo="foooo">Click FOOO</span>
<span class="two" ng-click="vm.openFoos($event) attr-foo="fo" attr-bar="bar">Click FOO BAR</span>
Clicking span.one throws the error "cannot find value of null" but clicking span.two works fine.
I do not want to write a controller for each instance of the combinations of keys in my query appearing on various html attributes; however, I'm getting this error.

instead of using
if (event.currentTarget.attributes.getNamedItem('attr-thing').value ....
use
if (event.currentTarget.attributes.getNamedItem('attr-thing') ....
When
event.currentTarget.attributes.getNamedItem('attr-thing')
does not exist, obviously one cannot take the value of it!

Could you be looking for hasOwnProperty?
object.hasOwnProperty("attrname"); // Yields true or false.

Related

Unable to access a property on a variable within a function. Uncaught TypeError:

I have a trivia app that is importing an array of objects called "questions". I have used getElementById to capture each of the buttons, and also added click event listeners for the "checkAnswer" function below.
However, I am getting the error: Uncaught TypeError: can't access property "correct", answer is undefined. This happens with any button I click.
I am using type="module" within the script tag in the HTML file.
The buttons are populating the correct text, but are not console logging any text like it should.
"randomQuestion" is a global variable that is being generated in another function within the same file. This is what it looks like:
randomQuestion = questions[Math.floor(Math.random()*questions.length)];
function checkAnswer(bntIndex) {
answer = randomQuestion.answers[bntIndex];
if (answer.correct === true) {
console.log("Correct!");
} else {
console.log("Incorrect");
}
}
It's rather a warning than an error.
You are getting those because you don't export this function and also don't use it anywhere

Property says it can't be read, even though it can read the property

Before I start, I just want to say I have very little experience with javascript, so maybe I'm missing something very obvious, but anyways.
I have an array of objects called Accommodations. I have the following code:
alert(this.quoteService.activeBasket.components.length);
This alert shows a length of 3, but I get a ton of errors saying:
An unexpected error has occurred. TypeError: Cannot read property 'length' of undefined
I'm just not sure how it's possible that it can read the .length property, but it's throwing errors that it can't...
Originally, the component object wasn't imported into this file, but even after importing it, I still have the same error...
Any help is greatly appreciated.
Edit:
Here is a little more context:
Basically I have an html file that has a radio button, this button should be greyed out, based on the method found in the ng-disabled tag:
<li class="c-3-12">
<div class="radio-btn" tl-field>
<input type="radio" class="radio" ng-model="vm.requiredBookingState"
ng-value="1" ng-disabled="!vm.validateOutfitLength()">
<label i18n>Confirmed</label>
</div>
</li>
Here is that method:
validateOutfitLength()
{
var rv = true;
let accoms: Accommodation[] = this.quoteService.activeBasket.accommodations;
accoms.forEach(accom => {
if (accom.outfitLength < 350) {
rv = false;
}
});
return rv;
}
The error for this code is different than above! The error for this is:
An unexpected error has occurred. TypeError: Cannot read property 'forEach' of undefined
This is a very large project that I'm working on, and I'm unaware if it's intentional that this method is being called many times... I assume it is intentional though.
Try this
alert(this.quoteService['activeBasket']['components'].length === undefined ? '' : this.quoteService['activeBasket']['components'].length);
This has been solved! I do want to give some credit to Chellappan, as I wouldn't have been able to find the solution without his answer.
Basically, there must be multiple calls to the validateOutfitLength method and within some of those calls, the quoteService.activeBasket.accommodations/components were undefined. The fix was simple, it was just basically checking whether the object was undefined before doing anything with the value.
let accoms = this.quoteService.activeBasket.accommodations;
if (typeof(accoms) != 'undefined') {
// do something with accoms
}

Fabric js extending toObject with custom properties, loses default ones

Befor posting this I've been looking up in here as in many other places, but I can get to have this working fully.
All I need is to be able to save some custom properties in all the shapes. The properties are : uuid, and rt_attributes.
Therefore, as by manual I added this code :
fabric.Object.prototype.toObject = (function(toObject) {
console.log(toObject)
return function() {
return fabric.util.object.extend(toObject.call(this), {
uuid: this.uuid,
rt_attributes: this.rt_attributes
});
};
})(fabric.Object.prototype.toObject);
which does work fine, up to a certain degree.
the problem comes when I serialize in json and load back.
the custom attributes are in , but shapes like the IText raise an exception such as :
fabric.js:22199 Uncaught TypeError: Cannot read property 'split' of undefined
Looking into the dumped json I can see the .text attribute is not exported. So My fear is that overriding the toObject I lose some of the custom attributes of the default object.
Of course I can redefine it in my toObject function with all the missing trims, but I though that
fabric.util.object.extend
would have done that for me.
Can someone point me on what I'm doing wrong ?
thanks.
L.
p.s
here is a snippet of the outcome json:
{"type":"i- text","originX":"left","originY":"top","left":29,"top":677,"width":107,"height":22.6,"fill":"rgba(255,255,255,1)","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"uuid":"04af6ab4-4eb1-432b-f46a-93b11a92292d","rt_attributes":[["fontFamily","text"],["fontSize","int"],["fill","color"],["opacity","float"],["top","int"],["left","int"]],"styles":{}},
as you can see there's no text field., but uuid and rt_attributes are in.
Finally found the proper way:
fabric.Object.prototype.toObject = (function (toObject) {
return function (propertiesToInclude) {
propertiesToInclude = (propertiesToInclude || []).concat(
['uuid','rt_attributes']
);
return toObject.apply(this, [propertiesToInclude]);
};
})(fabric.Object.prototype.toObject);

How to parse returned css information using Selenium webdriver.executescript

Newbie to Javascript in Node environment...
Using this code below where the script is getting css values for a particular web element, how do I parse this in javascript?
driver.executeScript(script, ele).then(p => {
console.log(p);
})
The code above shows this result in the console.
{ class: 'container ng-scope', 'ng-controller': 'CalcCtrl' }
It's returned as type Object, so I can't figure out for example how to get the value of the key "class"...
If I change the code to this:
driver.executeScript(script, ele).then(p => {
console.log(p);
var obj = JSON.parse(p);
console.log(obj.class);
})
I get this error...
Where column 27 is the parse in JSON.parse...
The answer to this question, is this:
driver.executeScript(script, ele).then(p => {
if(p.class) console.log(p.class);
})
JavaScript returns undefined for any key in a JSON object that cannot be found, therefore, the If(p.class) ensures this item of data has a key named class and prints it out.

Change View in mvc based on dropdownlist item selection

I have a dropdownlist on a View as:
<p>
#Html.DropDownList("Status", new List<SelectListItem>
{
new SelectListItem{ Text = "Show Active", Value = "0" },
new SelectListItem{ Text = "Show Deleted", Value = "1" }},
new
{
onchange = #"
var form = document.forms[0];
form.action='deletedDistricts';
form.submit();"
})
and I am referring it to controller action as:
[HttpPost]
[ActionName("deletedDistricts")]
public ActionResult deletedDistricts()
{
var d = hc.deletedDistricts.ToList();
return View(d);
}
but JavaScript is giving a runtime error as:
0x800a138f - JavaScript runtime error: Unable to set property 'action' of undefined or null reference
I am not very good at JavaScript. Any idea why this code is throwing Null reference?
Well I can't see that you would have a form associated with a dropdown, make sure that it's wrapped with:
#using(Html.BeginForm("deletedDistricts", controllerName, FormMethod.Post)) {
// drowpdown here
}
And remove form.action='deletedDistricts';
conrollerName should be name of your controller as a string.
Let's read the error you are getting once again:
0x800a138f - JavaScript runtime error: Unable to set property 'action'
of undefined or null reference
OK, now let's read your code once again to see where you are attempting to set an action property. Looks like that's happening right over here:
form.action='deletedDistricts';
Alright, so it seems like the form instance is undefined at this stage. So the obvious next step you would like to look at is where is this form instance coming from. And you wouldn't be surprised to find this line of code of yours:
var form = document.forms[0];
Cool, you seem to be attempting to retrieve the first <form> element in your DOM. But do you have such element? Did you ever use the Html.BeginForm helper to render an HTML form? Answering those simple questions would definitely put you on the right track. Don't hesitate to inspect the markup you are generating in the browser. I am sure this would help you figure out the missing bits.

Categories