IE - "Error: Object doesn't support this action" - javascript

I'm getting a frustrating javascript error in IE7 that I can't get around. It is working fine in Chrome and Firefox, but not in IE..
The line I am getting the error in is: item = listGetAt(list,'1','-');
This is calling the following custom method:
function listGetAt(list,position,delimiter) {
if(delimiter == null) { delimiter = '-'; }
list = list.split(delimiter);
if(list.length > position) {
return list[position];
} else {
return list.length;
}
}
Can anyone see something I can't?
Many thanks in advance for any help.
Jason

Poor code
Why pass a string as a numeric parameter?
I would consider
function listGetAt(list,position,delimiter) {
delimiter = delimiter || '-';
if (list.indexOf(delimiter) ==-1) return -1;
list = list.split(delimiter);
return list.length>=position?list[position]:null;
}

Related

JavaScript .startWith() function not working in IE, inside angularjs project

Hi im using Angularjs for my project, There is nationality search drop down. I want to map which is typing on Input and filter it inside nationality JSON object. This part is working fine in other browsers except IE. There is console error "Object doesn't support property or method 'startsWith'". this is my code, Can i know how to add "String.prototype.startsWith" for this issue for my code.
$scope.searchNationality = function (data) {
var output = [];
if (data != "" && data != undefined) {
$scope.ShowNationalityDropDown = true;
for (var i = 0; i < $scope.nationalityList.length; i++) {
if ($scope.nationalityList[i].content.toLowerCase().startsWith(data.toLowerCase())) {
output.push($scope.nationalityList[i]);
}
}
$scope.nationalityListSearchResults = output;
} else {
$scope.ShowNationalityDropDown = false;
$scope.nationalityListSearchResults = [];
}
};
You can try changing from .startsWith to .indexOf since it is compatible with IE for lower versions. If .indexOf returns 0 then the string is in the first position of the string that calls that function, which can be usable when you are in this kind of situation that you can't use .startsWith().
const str = "Hey this is a sample string!"
console.log(str.indexOf("Hey") === 0)
console.log(str.indexOf("sample") === 0)
$scope.searchNationality = function (data) {
var thereIsData = data != "" && data != undefined;
var output = thereIsData
? $scope.nationalityList.filter(function (nationality) {
return nationality.content.toLowerCase().indexOf(data.toLowerCase())) == 0;
})
: [];
$scope.ShowNationalityDropDown = thereIsData;
}

Why am I getting TypeError on length property

Getting this error:
TypeError: Cannot read property 'length' of undefined
For this code:
var getSuggestions = function(query) {
searchService.getSuggestions(query).then(function(es_return){
var suggestions = es_return.suggest.phraseSuggestion;
var results = es_return.hits.hits;
if (suggestions.length > 0) {
$scope.autocomplete.suggestions = suggestions;
}
else {
$scope.autocomplete.suggestions = [];
}
if (results.length > 0) {
$scope.autocomplete.results = results;
}
else {
$scope.autocomplete.results = [];
}
if (suggestions.length > 0 || results.length > 0) {
$scope.showAutocomplete = true;
}
else {
$scope.showAutocomplete = false;
}
});
};
Specifically on the first if statement and I don't see why? Need some fresh eyes to show me what I'm doing wrong.
I think you need some better null handling. With Suggestion.length > 0 null cannot be evaluated with >, right? So probably use boolean instead (or both).
if (Suggestion.length){
//do stuff
}
It looks like your es_return.suggest.phraseSuggestion is undefined.You can try like this:
if(suggestions != undefined)
{
if (suggestions.length > 0) {
$scope.autocomplete.suggestions = suggestions;
}
else {
$scope.autocomplete.suggestions = [];
}
}
Try to debug the code from the developer console.
Probably you should es_return.hits.hits remake to es_return.hits.
In your case es_return.hits.hits or suggestions are not an array.
After I drilled down on this more, I noticed that I had an issue with the ES query that I was using for the ac code. It was actually just a typo. Where I had phrasesuggestion in the js, I had phrase_suggestion in the json query for ES, once I fixed that - it worked! Thanks for your efforts.

JavaScript files.length not working in ie9 need alternative approach

I have the following JavaScript function which is failing in internet explorer 9 on the line which declares the variable filesattached.
function VesselDetails() {
insurancestart = $('#ctl00_ContentPlaceHolder1_datetimepickerinsstart').val();
insuranceend = $('#ctl00_ContentPlaceHolder1_datetimepickerinsend').val();
filesattached = $("input:File")[0].files.length;
//set up JS objects
$('#ctl00_ContentPlaceHolder1_datetimepickerinsend').datetimepicker({ format: 'd/m/Y H:i a' });
$('#ctl00_ContentPlaceHolder1_datetimepickerinsstart').datetimepicker({ format: 'd/m/Y H:i a' });
//subscribe to change events
$('#ctl00_ContentPlaceHolder1_datetimepickerinsstart').change(function () {
insurancestart = $("ctl00_ContentPlaceHolder1_datetimepickerinsstart").val();
});
$('#ctl00_ContentPlaceHolder1_datetimepickerinsend').change(function () {
insuranceend = $("ctl00_ContentPlaceHolder1_datetimepickerinsend").val();
});
$("input:File").change(function () {
filesattached = $("input:File")[0].files.length;
});
ins_client();
}
The ins_client method looks like this:
function ins_client(sender, e) {
if (pagemode == 'EditVessel') {
e.IsValid = true;
}
if (pagemode == 'NewVessel') {
if (insurancestart !== '' && insuranceend !== '' && filesattached > 0) {
e.IsValid = true;
}
else {
e.IsValid = false;
}
}
}
This all works perfectly well in chrome and ie 11 but the length property is returning an undefined for ie 9. I am using the length because I only want the page to be valid for a new vessel request once a document has been submitted, is there another way of doing this which will work in ie 9 onwards and chrome, apologies if this has already been answered elsewhere but I cannot find a workaround anywhere that enables this to continue working in the same way but in ie9 onwards and chrome.
I replaced:
filesattached = $("input:File")[0].files.length;
With:
var areFilesAttached = document.getElementById('ctl00_ContentPlaceHolder1_fuAttachment').value ? true : false;
Within the VesselDetails function.
Then replaced the if statement within ins_client with the following:
if (pagemode == 'NewVessel') {
if (insurancestart !== '' && insuranceend !== '' && areFilesAttached == true) {
e.IsValid = true;
}
else {
e.IsValid = false;
}
}
This was an alternative approach which enabled me to check whether or not a file had been provided without using the files.length property which is not compatible with IE9.
I'm afraid this can't be achieved, IE9 does not support HTML5 File API and therefore it returns undefined value for files property.
Take a look at FILE API

What location.hash.match return if there is no hash?

please can you tell me what does location.hash.match return if there is no hash ?
My code :
function getHashValue(key) {
return location.hash.match(new RegExp(key + '=([^&]*)'))[1];
}
test = getHashValue('test');
if (test == 'abc') {
//code WORKS
}
else if (test == 'sal') {
//code WORKS
}
else if (test == "") {
//code DOESNT WORKS
}
but It doesn't works
I forget to mentionned that my code 'getHashValue' return the value of the hash Exemple : #test=abc
sorry I forget to mentionned it
Why not just?
test = getHashValue('test');
if (test === undefined) {
//code
}
EDIT
The error was from a null return in the match() call. The following change will return an empty string if the match is "" or null.
function getHashValue(key) {
var match = location.hash .match(new RegExp(key + '=([^&]*)'));
return match ? match[1] : "";
}
If you run location.hash in your browser console on any website where you're not using a hash, you'll find that it returns the empty string "".
As such, a regex match on that will find 0 results, returning null, at which point, you try to access null[1]...
location.hash will be empty string and your function:
function getHashValue(key) {
return location.hash.match(new RegExp(key + '=([^&]*)'))[1];
}
Will indeed return undefined. The problem is that you are checking "undefined" value incorrectly. Change your code to:
test = getHashValue('test');
if (typeof(test) === 'undefined') {
//code
}

Javascript for conditional URL append or redirect based on window.location.href

I am trying to make a bookmarklet that when clicked will check the URL of the current tab/window to see if it contains 'char1' and/or 'char2' (a given character). If both chars are present it redirects to another URL, for the other two it will append the current URL respectively.
I believe there must be a more elegant way of stating this than the following (which has so far worked perfectly for me) but I don't have great knowledge of Javascript. My (unwieldy & repetitive) working code (apologies):
if (window.location.href.indexOf('char1') != -1 &&
window.location.href.indexOf('char2') != -1)
{
window.location="https://website.com/";
}
else if (window.location.href.indexOf('char1') != -1)
{
window.location.assign(window.location.href += 'append1');
}
else if (window.location.href.indexOf('char2') != -1)
{
window.location.assign(window.location.href += 'append2');
}
Does exactly what I need it to but, well... not very graceful to say the least.
Is there a simpler way to do this, perhaps with vars or a pseudo-object? Or better code?
A (sort-of) refactoring of dthorpe's suggestion:
var hasC1 = window.location.href.indexOf('char1')!=-1
var hasC2 = window.location.href.indexOf('char2')!=-1
var newLoc = hasC1
? hasC2 ? "https://website.com/" : window.location.href+'append1'
: hasC2 ? window.location.href+'append1' : '';
if (newLoc)
window.location = newLoc;
Calling assign is the same as assigning a value to window.location, you were doing both with the addition assignment += operator in the method anyway:
window.location.assign(window.location.href+='append2')
This would actually assign "append2" to the end of window.location.href before calling the assign method, making it redundant.
You could also reduce DOM lookups by setting window.location to a var.
The only reduction I can see is to pull out the redundant indexof calls into vars and then test the vars. It's not going to make any appreciable difference in performance though.
var hasChar1 = window.location.href.indexOf('char1') != -1;
var hasChar2 = window.location.href.indexOf('char2') != -1;
if (hasChar1)
{
if (hasChar2)
{
window.location="https://website.com/";
}
else
{
window.location.assign(window.location.href+='append1');
}
}
else if (hasChar2)
{
window.location.assign(window.location.href+='append2');
}
Kind of extendable code. Am i crazy?
var loc = window.location.href;
var arr = [{
url: "https://website.com/",
chars: ["char1", "char2"]
}, {
url: loc + "append1",
chars: ["char1"]
}, {
url: loc + "append2",
chars: ["char2"]
}];
function containsChars(str, chars)
{
var contains = true;
for(index in chars) {
if(str.indexOf(chars[index]) == -1) {
contains = false;
break;
}
}
return contains;
}
for(index in arr) {
var item = arr[index];
if(containsChars(loc, item.chars)) {
window.location.href = item.url;
break;
}
}
var location =window.location.href
if (location.indexOf('char1')!=-1 && location.indexOf('char2')!=-1)
{window.location="https://website.com/";}
else if (location.href.indexOf('char1')!=-1) {window.location.assign(location+='append1');}
else if (location.indexOf('char2')!=-1) {window.location.assign(location+='append2');}

Categories

Resources