Object doesn't support property or method 'slice' - javascript

I'm newbie to the Javascript/Jquery world.
I have a div with several links and i want to collect the url's .
Then i want to extract from those href's the last 9 characters (actually i wish to optimize it and collect the digits independently the length at the end of each string).I tried to extract them with the slice() method but it does not work.
In console the error is
Object doesn't support property or method 'slice'
Can i convert the object to a string ? Your help is appreciated !
The code is the following
$(document).ready(function(){
var $posts= $('a.entry_title').each(function(){
$(this).attr('href');
});
var posts1 = $posts[0].slice(-9);
var posts2 = $posts[1].slice(-9);
var posts = ["MyURL"+ posts1,"MyURL"+posts2]
$('#div1').load(posts[0] + " .shadow3");
$('#div2').load(posts[1] + " .shadow3");
});
</script>

You see Object doesn't support because $.each returns a jQuery object.
Use .map() instead because it returns an array on which slice would work
var $posts= $('a.entry_title').map(function(){
return $(this).attr('href');
});
Result would be
["link1", "link2", "link3"....] // just a sample
If you wish to get an array of hrefs with last nine characters of each link you can use map this way
var $posts= $('a.entry_title').map(function(){
return $(this).attr('href').slice(-9); // or you can do your own magic
});
Result would look like this
["k1", "k2", "k3"....] // after slicing the words

Try next one:
var hrefs = []; // list of collected and sliced hrefs.
var $posts= $('a.entry_title').each(function() {
// slice & push each href into list.
hrefs.push($(this).attr('href').slice(-9));
});
console.log('href list:', hrefs); // control result.
var posts = ["MyURL"+ hrefs[0],"MyURL"+hrefs[1]]

Related

Cannot do "split" in chrome's console

I am trying to get links from one page. Here's a simple code to get all links from certain dom element.
var $ = jQuery;
var page = $("#main .entry p");
var rez = [];
for(var i=0; i<page.length;i++) {
var title = $(page[i]).find("a").text();
var info = $(page[i]).text();
var page_url = $(page[i]).find("a").attr("href");
rez.push({
title: title,
page_url: page_url,
info: info
});
}
I am using this code in Chrome browser's console.
Everything works ok. rez array is populated, and I can veryfy it by something like console.table(rez).
Now I am trying to strip certain part from urls collected in previous step by using split
for(var i=0; i<rez.length;i++) {
console.log(rez[i].page_url); // <- this works
console.log(rez[i].page_url.split("http://something...")[1] ); // <- this fails
}
Important note! I am doing it all in one step by copying entire code (rez populating code and rez iterating in order to make split).
And I am getting this error in console:
VM7064:18 Uncaught TypeError: Cannot read property 'split' of undefined
at <anonymous>:18:29
Why??
The split() function is used to split a string into an array of substrings. In split function as parameter you have to put a separator for example:
"http://something...like-this.com/blablabla".split("/");
This will return you an array ["http:", "", "something...like-this.com", "blablabla"]
In your case you try to split by some text "http://something..." and to get the second element of the array [1]. This will return you undefined in all your cases.

Remove selector criteria in variable value

I'm creating an online shop, with specific links to products e.g. (http://example.com/products/phones/nexus-5).
I'm using the following code,
var get_product_availability_classname = $("[class$='_availability']").attr('class');
which selects (creates a variable with the value of) the element that has a class ending in "_availability".
Every product page has a different piece of text just before the _availability, like GOOGLENEXUS5_availability, SAMSUNG4KTV_availability, whatever_availability...
What I have to do now is to essentially remove the criteria I used to get that whole class name (i.e. class$='_availability'); using the example above it'd be trimmed from SAMSUNG4KTV_availability to SAMSUNG4KTV.
Possible solutions
I haven't figured how to, but we could use JavaScript's substring() or substr().
You will be best off using Regex in this situation. The following will look for the _availability in the classes string and if it finds it it will capture what came before.
var get_product_availability_classname = $("[class$='_availability']").attr('class');
var matches = /([^\s]*)_availability\b/g.exec(get_product_availability_classname)
if(matches.length > 1){
var your_id = matches[1];
}
Use attr() method with a callback and update the class name using String#replace method with word boundary regex.
Although use attribute contains selector since there is a chance to have multiple classes, in that case, the class can be at the start or between two classes.
var get_product_availability_classname = $("[class*='_availability '],[class$='_availability']");
get_product_availability_classname.attr('class',function(i,v){
return v.replace(/_availability\b/g,'');
});
var get_product_availability_classname = $("[class*='_availability '],[class$='_availability']");
get_product_availability_classname.attr('class', function(i, v) {
return v.replace(/_availability\b/, '');
});
console.log(document.body.innerHTML);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="abc_availability"></div>
<div class="abc_availability class"></div>
<div class="class abc_availability"></div>
<div class="class abc_availability class1"></div>
If there will only ever be a single _ in the class name
var get_product_availability_classname = $("[class$='_availability']").attr('class')
.split(' ') // split the class to individual classes
.filter(function(cls) { // filter ones with _availability
return cls.split('_').pop() == 'availability');
})[0]; // use first match
var product = get_product_availability_classname.split('_')[0]
.split('_') creates an array ["PRODUCT", "availability"] and the [0] selects the first item of this array
alternatively you could also
var product = get_product_availability_classname.split('_availability')[0]
this does the same thing, except it splits on the string _availability, and it doesn't matter how many _ in the prefix
If your string is always in the form x_y, where x and y don't contain an underscore, then you can use the split function to split on the underscore.
var str = "SAMSUNG4KTV_availability";
var result = str.split("_")[0];
console.log(result);
The split function returns an array of strings containing the substring in between each underscore, you use [0] to select the first element in the array.

how to find specific objects and put them in an array in javascript

I have this result in my script
'[{"region":"NCA","depprt":"Havana, Cuba"},{"region":"NCA","depprt":"Havana, Cuba"},{"region":"NCA","depprt":"Montego Bay, Jamaica"},{"region":"NCA","depprt":"Montego Bay, Jamaica"}]'
this is the code to get it.
var jsonList = '#Html.Raw(Json.Encode(ViewBag.chk))'
var jsList = JSON.stringify(jsonList);
for jsList I got above result.now I want to get all depprt where region is equal to NCA.how can I do that.
You can use the .filter() method for this.
var ncaList = jsonList.filter(function(obj){ return obj.region == "NCA"; });
Very simple. Iterate over the jList array and see if the region property matches your condition or not then append the item to your filtered array.
var filtered = [];
jList.forEach(function(item) {
if(item.region == 'NCA') {
filtered.push(item);
}
});
Just iterate over it:
var filteredDepprts = [];
jsList.forEach(function(element){
if(element.region == 'NCA'){
filteredList.push(element.depprt); //or element if you want to push the full object
}
});
The JSON.stringify method converts a JavaScript value to a string.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
When you want to convert a JSON string to a JavaScript value, use JSON.parse
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
var jsonList = '#Html.Raw(Json.Encode(ViewBag.chk))'
var jsList = JSON.parse(jsonList);
Using single quotes around your #Html.Raw, creates a string and not a JavaScript value. The filter method does not work on strings
Eventually you could use Array.prototype.filter Filter out each element in array, that matches your criteria.
https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Try map:
var obj= [];
for (i in jsonList) {
if (jsonList[i].region == "NCA") { obj.push(jsonList[i])};
}
https://jsfiddle.net/pd6hvn78/

XML - get all values from tags into an array

I have what I am sure is a very straightforward question! I have an xml document and, using AJAX, I am wanting to get the values from tags with the same name into an array. XML:
<data>
<instance>
<term>Dog</term>
<clicks>11235</clicks>
</instance>
<instance>
<term>Cat</term>
<clicks>6309</clicks>
</instance>
</data>
My Javascript:
console.log(xml.getElementsByTagName("clicks")[0].childNodes[0].nodeValue);
This only seems to return the first value. How do you return them all?
Try i wrote in java, I think you have to change the array part. hope this helps.
NodeList clicks = xml.getElementsByTagName("clicks")
int[] clickArray = new int[clicks.getLength()];
for(int i=0; i<clicks.getLength();i++){
clickArray[i] = clicks[i].childNodes[0].nodeValue;
}
function test(){
var clicks = xml.getElementsByTagName("clicks");
var result = new Array();
foreach(var c in clicks){
console.log(c);
result.push(c.childNodes[0].nodeValue);
}
return result;
}
this should print all "click" tags. In your result array now are all values, but note that this just works, if the tag "structure" is always the one you posted above
You can use jQuery to get all tags, and then use .each() to get all values:
$(xml).find('clicks').each(function(){
console.log($(this).html());
});
or if you want to get an array, you can use .map() function:
var list = $(xml).find('clicks').map(function(){
return $(this).html();
}).get();
Using d3.js you can do something like this:
Define a div in your DOM <div></div>
var list = d3.select('div')
.html(xml) // set the xml content
.selectAll('clicks')
.each(function(){
console.log(this.innerHTML);
});
console.log(list); //you can do what you want with all clicks elements

putting source of all images into an array

What is the cleanest way to put the source attribute string of all images within a div into an array?
I was hoping this would work -
var imageSourceArray = $("#leDiv img").attr('src');
alert(imageSourceArray[3]); //not alerting the source, boo hoo.
Do I need to loop through $("#leDiv img") and add each src string to an array individually? Or is there a more elegant way to do this?
You can use jQuery's map function which is described as:
Pass each element in the current matched set through a function, producing a new jQuery object containing the return values.
For your example:
var mySources = $('#leDiv img').map(function() {
return $(this).attr('src');
}).get();
Edit: Far more elegant solution, there's obviously still some looping involved internally:
var img_sources = $('#leDiv img').map(function(){ return $(this).attr('src') });
You will in fact need to loop over the collection and add sources individually.
var img_sources = [];
$('#leDiv img').each(function(i,e){
img_sources.push($(e).attr('src'))
})
Some background: jQuery.fn.attr() maps to jQuery.access() internally, the key part of which looks like this:
function( elems, key, value, exec, fn, pass ) {
var length = elems.length;
// setter functions omitted here …
// Getting an attribute
return length ? fn( elems[0], key ) : undefined;
}
Note the elems[0] part – only the first item in the collection is fed to the subsequent callback function (jQuery.attr() in fact) responsible for extracting the information.
var imageSourceArray = [];
$('#leDiv img').each(function(){
var src = $(this).attr("src");
imageSourceArray.push(src);
});
alert(imageSourceArray[3]);
you already have the src in a collection when you fetch the the images. It may be more efficient to not store the src attributes in another array:
$('#leDiv img').each(function(i,e){
var dosomethingwith = $(e).attr('src');
})
or you could do:
var ImageCol = $('#leDiv img');
alert(ImageCol[3].attr('src'));

Categories