multiple search pattern from string - javascript

I have this code below to search for a string of search string_search_* matched.
I'm wondering if there's any easier way to do this like maybe add multiple search term in indexof? is that possible?
My goal: just add variable string:
string_search4, 5, 6 and so on..
string = "this is a .bigcommerce.com site";
var string_search1 = 'cdn.shopify.com/s';
var string_search2 = '.bigcommerce.com/';
var string_search3 = 'woocommerce/';
// start checkig with SHOPIFY first
var s = string.indexOf(string_search1 );
var found_s = String(s);
// IF FOUND - look for the full url hubspot - like the mp4 url
if (found_s != '-1') {
var result = 'SHOPIFY'
return result;
}
// if NOT FOUND, check with BIGCOMMERCE
else {
var b = html.indexOf(string_search2);
var found_b = String(b);
if (found_b != '-1') {
var result = 'BIGCOMMERCE'
return result;
}
else {
var w = html.indexOf(string_search3);
var found_w = String(w);
if (found_w != '-1') {
var result = 'WOO COMMERCE'
return result;
}
else {
var result = 'CANNOT INDENTIFY CMS'
return result
}
}
}

This may look a little long, but is very expandable.
// Our "key" object and defaults
var sObj = function(id){
this.id = id;
this.found = false;
};
// Our self-contained object with search and result
// functions. This is were and how we can expand quickly
var s = {
'ob': [],
'find': function(haystack) {
if (this.ob) {
for(var x in this.ob) {
this.ob[x].found = (haystack.indexOf(this.ob[x].id) > -1);
}
}
},
'result': function() {
var r = "";
if (this.ob) {
for(var x in this.ob) {
if (this.ob[x].found) {
r += ","+this.ob[x].id;
}
}
}
return (r == "") ? r : r.substr(1);
}
};
// Create the object array with the "id"
// Add as many as you want.
s.ob.push(new sObj('shopify.com'));
s.ob.push(new sObj('bigcommerce.com'));
s.ob.push(new sObj('woocommerce.com'));
// quick debug for testing
//for(var x in s.ob) {
// console.log('x:['+ x +']['+ s.ob[x].id +']['+ s.ob[x].found +']');
//}
// Our string to be tested
var data = "this is a .bigcommerce.com site";
// check if the data matches one of the sObj ids
s.find(data);
// get the results
console.log('result:['+ s.result() +']');
// And for a second test (2 results)
data = "can you shopify.com or woocommerce.com me?";
s.find(data);
console.log('result:['+ s.result() +']');

Related

JavaScript array has elements but length is zero

I've done some searching around the web and nothing seems to solve my problem. I have the following jQuery code:
function youtube_data_parser(data) {
//---> parse video data - start
var qsToJson = function(qs) {
var res = {};
var pars = qs.split('&');
var kv, k, v;
for (i in pars) {
kv = pars[i].split('=');
k = kv[0];
v = kv[1];
res[k] = decodeURIComponent(v);
}
return res;
}
//---> parse video data - end
var get_video_info = qsToJson(data);
if (get_video_info.status == 'fail') {
return {
status: "error",
code: "invalid_url",
msg: "check your url or video id"
};
} else {
// remapping urls into an array of objects
//--->parse > url_encoded_fmt_stream_map > start
//will get the video urls
var tmp = get_video_info["url_encoded_fmt_stream_map"];
if (tmp) {
tmp = tmp.split(',');
for (i in tmp) {
tmp[i] = qsToJson(tmp[i]);
}
get_video_info["url_encoded_fmt_stream_map"] = tmp;
}
//--->parse > url_encoded_fmt_stream_map > end
//--->parse > player_response > start
var tmp1 = get_video_info["player_response"];
if (tmp1) {
get_video_info["player_response"] = JSON.parse(tmp1);
}
//--->parse > player_response > end
//--->parse > keywords > start
var keywords = get_video_info["keywords"];
if (keywords) {
key_words = keywords.replace(/\+/g, ' ').split(',');
for (i in key_words) {
keywords[i] = qsToJson(key_words[i]);
}
get_video_info["keywords"] = {
all: keywords.replace(/\+/g, ' '),
arr: key_words
};
}
//--->parse > keywords > end
//return data
return {
status: 'success',
raw_data: qsToJson(data),
video_info: get_video_info
};
}
}
function getVideoInfo() {
var get_video_url = $('#ytdlUrl').val();
var get_video_id = getUrlVars(get_video_url)['v'];
var video_arr_final = [];
var ajax_url = "video_info.php?id=" + get_video_id;
$.get(ajax_url, function(d1) {
var data = youtube_data_parser(d1);
var video_data = data.video_info;
var player_info = data.video_info.player_response;
var video_title = player_info.videoDetails.title.replace(/\+/g, ' ');
var fmt_list = video_data.fmt_list.split(',');
var video_thumbnail_url = video_data.thumbnail_url;
var video_arr = video_data.url_encoded_fmt_stream_map;
//create video file array
$.each(video_arr, function(i1, v1) {
var valueToPush = {};
valueToPush.video_url = v1.url;
valueToPush.video_thumbnail_url = video_thumbnail_url;
valueToPush.video_title = video_title;
$.each(fmt_list, function(i2, v2) {
var fmt = v2.split('/');
var fmt_id = fmt[0];
var fmt_quality = fmt[1];
if (fmt_id == v1.itag) {
valueToPush.fmt_id = fmt_id;
valueToPush.fmt_quality = fmt_quality;
}
});
video_arr_final.push(valueToPush);
});
});
return video_arr_final;
}
function getUrlVars(url) {
var vars = {};
var parts = url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) {
vars[key] = value;
});
return vars;
}
function fillInOptions(ytOptions) {
//console.log(ytOptions);
//alert(ytOptions[0]);
var ytFill = ytOptions;
console.log(ytFill);
//ytFill.forEach(function(i,v) {
var ytdlOptions = $('#ytdlOptions');
ytFill.forEach(function(i,v) {
console.log(i);
ytdlOptions.append(new Option(v.fmt_quality, v.fmt_id));
});
return true;
}
function showYTDLLoader() {
$('#ytdlInput').fadeOut(1000, function() {
$('#ytdlLoader').fadeIn(500);
});
var options = getVideoInfo();
//console.log(options);
if (fillInOptions(options) == true) {
//do rest
}
}
function showYTDLOptions() {
return true;
}
function startDownload() {
showYTDLLoader();
}
function hideYTDLLoader() {
$('#ytdlLoader').fadeOut(500);
}
function animateCSS(element, animationName, callback) {
const node = $(element);
node.addClass(animationName);
function handleAnimationEnd() {
node.removeClass(animationName);
node.animationend = null;
if (typeof callback === 'function') callback();
}
node.animationend = handleAnimationEnd();
}
When my button is clicked, I call showYTDLLoader() which gets an array of objects from the YouTube API that looks like this:
[
{
"video_url": "https://r7---sn-uxanug5-cox6.googlevideo.com/videoplayback?expire=1572496003&ei=Iw66Xa24H8PL3LUPiN25mAs&ip=2001%3A8003%3A749b%3Aa01%3A5cd8%3Ac610%3A6402%3Ad0fe&id=o-ADsVnoOoBQ6-SWzYZU7gHES06s7xQptJG6hn9WcakITY&itag=22&source=youtube&requiressl=yes&mm=31%2C29&mn=sn-uxanug5-cox6%2Csn-ntqe6n7r&ms=au%2Crdu&mv=m&mvi=6&pl=39&initcwndbps=1655000&mime=video%2Fmp4&ratebypass=yes&dur=917.768&lmt=1572418007364260&mt=1572474311&fvip=4&fexp=23842630&c=WEB&txp=5535432&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cmime%2Cratebypass%2Cdur%2Clmt&sig=ALgxI2wwRgIhAIp-4gyUTLoXFetbY0ha_YnR7DJqsp_MNjjIxqDdfPZJAiEA_WPd21jgX9broBcigf8rcSEVoJb2_NX7t3XZQqytsSM%3D&lsparams=mm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AHylml4wRAIgacvP3zjEq-rVEZFrX7a_hC6TR-Zab7Ii-Fbaupjs_PcCIHdZht4l4ioYL3ERz7WNiSbnOnhm5iYxEECaQXPP2hUp",
"video_title": "Arnold Schwarzenegger on Son-in-law Chris Pratt, Pranking Sylvester Stallone & Terminator’s Return",
"fmt_id": "22",
"fmt_quality": "1280x720"
},
{
"video_url": "https://r7---sn-uxanug5-cox6.googlevideo.com/videoplayback?expire=1572496003&ei=Iw66Xa24H8PL3LUPiN25mAs&ip=2001%3A8003%3A749b%3Aa01%3A5cd8%3Ac610%3A6402%3Ad0fe&id=o-ADsVnoOoBQ6-SWzYZU7gHES06s7xQptJG6hn9WcakITY&itag=18&source=youtube&requiressl=yes&mm=31%2C29&mn=sn-uxanug5-cox6%2Csn-ntqe6n7r&ms=au%2Crdu&mv=m&mvi=6&pl=39&initcwndbps=1655000&mime=video%2Fmp4&gir=yes&clen=44248820&ratebypass=yes&dur=917.768&lmt=1572416976690256&mt=1572474311&fvip=4&fexp=23842630&c=WEB&txp=5531432&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cmime%2Cgir%2Cclen%2Cratebypass%2Cdur%2Clmt&sig=ALgxI2wwRQIhANTZJlBHFWQWCnfK11yvLiPUV26c6NzvqIMKjDwmsByMAiBUSy0ZJMo4GdHSiRU4xBDDLxLtzwKZAqAKCiB-1aViDQ%3D%3D&lsparams=mm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AHylml4wRAIgacvP3zjEq-rVEZFrX7a_hC6TR-Zab7Ii-Fbaupjs_PcCIHdZht4l4ioYL3ERz7WNiSbnOnhm5iYxEECaQXPP2hUp",
"video_title": "Arnold Schwarzenegger on Son-in-law Chris Pratt, Pranking Sylvester Stallone & Terminator’s Return",
"fmt_id": "18",
"fmt_quality": "640x360"
}
]
But when I try and loop through each entry with fillInOptions(), my loop is never completed because the length is apparently zero. However, when I dump the array using console.log() it tells me the length is 2, and displays the above. I need to be able to add each option to my dropdown.
Thankyou!
UPDATE: Added full code, sorry!
It looks like your .forEach() is the root of the problem. The parameters of a forEach are currentValue, index like this: array.forEach(function(currentValue, index) {}); but it looks like you're using them in the opposite way
Try rewriting that iteration to this:
ytFill.forEach(function(v, i) {
console.log(i);
ytdlOptions.append(new Option(v.fmt_quality, v.fmt_id));
});
Notice the difference in the order of v and i in the parameters.

How to pass filter value from URL after rebuilding url with the goal of implementing infinite scroll using Angular2 and Typescript?

I have a search page where you can search books and apply several filters. On allpying filter I am sending the request in the URL to server. I have implemented that using the following javascript ->
$(document).ready(function(){
var base_url = 'https://'+window.location.hostname;
var url = base_url+'/books/search/';
var next_url = base_url+'/books/search/next/';
var filter_url = base_url+'/books/search/filter/';
var search_input = $('.search-bar input');
var bookSeach = {
searchQueryAsString : function(el){
var id = $(el).attr('id');
var id = id.substr(id.lastIndexOf('_')+1)
var filter_type = $(el).closest('ul.p-search-var-items').attr('filter-type')
var name = $(el).val();
$('#'+filter_type+'_id').val(id)
$('#'+filter_type+'_name').val(name)
return this.buildSearchQuery()
},
searchQueryAsArray : function(el){
el.find('input:checkbox:checked').each(function(){
var filter=$(this).closest('.p-search-var-items').attr('filter-type')
var id = $(this).attr('id')
var name = $(this).val()
id = id.substr(id.lastIndexOf('_')+1)
var value = $('#'+filter+'_id').val()!='' ?$('#'+filter+'_id').val()+','+id : id
$('#'+filter+'_id').val(value)
var nvalue = $('#'+filter+'_name').val()!='' ?$('#'+filter+'_name').val()+','+name : name
$('#'+filter+'_name').val(nvalue)
})
return this.buildSearchQuery()
},
buildSearchQuery : function(){
var self = this;
var query_url = base_url+'/books/search/';
$('input.filter_value').each(function(){
var el = $(this);
if(el.val()!=''){
value = $.trim(el.val())
query_url = self.updateQueryStringParameter(query_url,el.attr('id'),value)
next_url = self.updateQueryStringParameter(next_url,el.attr('id'),value)
filter_url = self.updateQueryStringParameter(filter_url,el.attr('id'),value)
}
})
return {'url':query_url,'next_url':next_url,'filter_url':filter_url};
},
updateQueryStringParameter : function(uri, key, value) {
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
return uri.replace(re, '$1' + key + "=" + value + '$2');
}
else {
return uri + separator + key + "=" + value;
}
},
filterText : function (elem) {
var value = elem.val().toLowerCase();
var filter = elem.attr('data-filter')
$(".p-search-var-items[filter-type='"+filter+"'] > li").each(function() {
if ($(this).text().toLowerCase().search(value) > -1) {
$(this).show();
}
else {
$(this).hide();
}
});
},
loadBooksOnScroll : function(count){
var ajax_url = bookSeach.buildSearchQuery()
if($('#dropdownMenu1').attr('data-filter-applied')!=''){
ajax_url = ajax_url['filter_url']
data = {'index':count,'type':$('#dropdownMenu1').attr('data-filter-applied')}
}else{
ajax_url = ajax_url['next_url']
data = {'index':count}
}
this.ajaxHandler(ajax_url,'GET',data,this.renderBookList)
},
loadBooksOnSort : function(type){
var ajax_url = bookSeach.buildSearchQuery()
ajax_url = ajax_url['filter_url']
this.ajaxHandler(ajax_url,'GET',{'index':0,'type':type},function(response){
$('.p-result').html('')
bookSeach.renderBookList(response)
})
},
ajaxHandler : function(url,method,data,callback){
$.ajax({
'url':url,
'type':method,
'data':data,
'success':function(response){
if(response){
callback(response)
}
}
})
},
filterContentByKeyWord: function(key,type){
var keyword = {}
keyword[type+'_key']=key
var ajax_url = base_url+'/'+type+'s/search/';
this.ajaxHandler(ajax_url,'GET',keyword,function(result){
bookSeach.renderFilterContent(result,type)
})
},
renderFilterContent: function(results,type){
$('.'+type+'-results').html('')
var template =_.template($('#'+type+'_template').html())
var id = this.getUrlParameter(type+'_id')
console.log(id, results,id)
$('.'+type+'-results').append(template({'results':results,'id':id}))
},
renderBookList : function(books){
var template =_.template($('#book_detail').html())
$('.p-result').append(template({'books':books}))
},
removeParameter : function(url, parameter){
var urlparts= url.split('?');
if (urlparts.length>=2)
{
var urlBase=urlparts.shift(); //get first part, and remove from array
var queryString=urlparts.join("?"); //join it back up
var prefix = encodeURIComponent(parameter)+'=';
var pars = queryString.split(/[&;]/g);
for (var i= pars.length; i-->0;)
if (pars[i].lastIndexOf(prefix, 0)!==-1) //idiom for string.startsWith
pars.splice(i, 1);
url = urlBase+'?'+pars.join('&');
}
return url;
},
getUrlParameter : function(sParam){
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++)
{
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == sParam)
{
return sParameterName[1];
}
}
}
};
// Search within filters by keyword - START
//Delay function to prevent calling the function on every key press
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
//On keyup for search within filters
$('.p-search-cat-box').on('keyup',function(){
var self = this
delay(function(){
var filter = $(self).attr('data-filter');
if(filter=='author' || filter=='publisher' || filter=='seller' || filter=='institute'){
$('#'+filter+'_key').val($(self).val())
bookSeach.filterContentByKeyWord($(self).val(),filter)
}else{
bookSeach.filterText($(self))
}
}, 600 )
});
// Search within filters by keyword - END
//Filters on change event - START
// For category and sub category
$('.p-search-var-items input:radio').on('change',function(){
var redirect_url = bookSeach.searchQueryAsString($(this))
window.location.href = redirect_url['url'];
})
// For Authors, Publishers and Binding
$(document).on('change','.p-search-var-items input:checkbox',function(){
elem = $(this)
el = elem.closest('.p-search-var-items')
$('#'+el.attr('filter-type')+'_id').val('')
$('#'+el.attr('filter-type')+'_name').val('')
var redirect_url = bookSeach.searchQueryAsArray(elem.closest('.p-search-cat-list'))
window.location.href = redirect_url['url'];
})
//Filters on change event - END
// Filters - collapse up and down - START
$('.filter-container .p-sub-cat i').on('click',function(){
if($(this).hasClass('fa-minus')){
$(this).closest('.filter-container').find('.p-search-cat').hide("slide",{direction:'up'},500)
$(this).removeClass('fa-minus')
$(this).addClass('fa-plus')
}else{
$(this).closest('.filter-container').find('.p-search-cat').show("slide",{direction:'up'},500)
$(this).removeClass('fa-plus')
$(this).addClass('fa-minus')
}
})
// Filters - collapse up and down - END
//Search box Header - START
$('#search_books').on('click',function(){
var redirect_url = bookSeach.buildSearchQuery()
window.location.href = redirect_url['url'];
})
$("#query").keyup(function(event){
if(event.keyCode == 13){
$("#search_books").trigger('click');
}
});
//Search box Header - END
//Applied FIlters - remove option
$('.p-filter-title img').on('click',function(){
var param = $(this).attr('data-applied-filter')
if(param=='author' || param=='publisher' || param=='seller' || param=='institute' || param=='binding' ){
var id = $(this).attr('data-filter-id')
$('#'+param+'_'+id).removeAttr('checked')
$('#'+param+'_'+id).trigger('change')
}else{
var paramname = param.substr(0,param.lastIndexOf('_')+1)
url = bookSeach.removeParameter(window.location.href,paramname+'name')
redirect_url = bookSeach.removeParameter(url,param)
window.location.href = redirect_url
}
})
//Infinite Scroll - Book Results - START
if(location.href.indexOf('books/search/')>0){
var count =10;
$(window).scroll(function(){
if ($(window).scrollTop() == $(document).height() - $(window).height()){
bookSeach.loadBooksOnScroll(count);
count+=10;
}
});
}
//Infinite Scroll - Book Results - END
//Filters in Responsive Layout - START
$('.apply').on('click',function(){
$('.mobile-filters ul.p-search-var-items span.m_apply_filter').each(function(){
if($(this).attr('data-is-selected')=='true'){
var id = $(this).attr('data-id')
var type = $(this).attr('data-type')
var value = $('#m_'+type+'_id').val()!=''? $('#m_'+type+'_id').val()+','+id : id
$('#m_'+type+'_id').val(value)
}
})
$('.m_filter').each(function(){
var param = $(this).attr('id');
param = param.substr(param.indexOf('m_')+2)
value = $.trim($(this).val())
redirect_url = bookSeach.updateQueryStringParameter(url,param,value)
})
window.location.href = redirect_url
})
$('.m_apply_filter').on('click',function(){
if($(this).attr('data-is-selected')=='false'){
$(this).closest('li').addClass('p-search-var-items-active')
$(this).attr('data-is-selected','true')
}else{
$(this).closest('li').removeClass('p-search-var-items-active')
$(this).attr('data-is-selected','false')
}
})
//Filters in Responsive Layout - END
$('.back-to-top').on('click', function(){
$(window).scrollTop(0 )
})
$(window).on('scroll', function(){
if($(window).scrollTop()>1200){
$('.back-to-top').removeClass('hide')
}else{
$('.back-to-top').addClass('hide')
}
})
$('.presentation a').on('click', function(e){
e.preventDefault();
var type= $(this).data('type')
bookSeach.loadBooksOnSort(type)
$('#dropdownMenu1 .sort_filter').text('Sort by :'+type)
$('#dropdownMenu1').attr('data-filter-applied',type)
})
}
})
})
What it does is when you select a filters it changes the url makes a server call and displays the data accordingly.
It also implements infinite scroll on scrolling down it loads 10 more results.
I want to implement the entire thing using Angular2 with typescript. Can someone please suggest me how to implement my js code using typescritp and Angular2. I am new to angular so I am having some problem in implementing the same.
Thank you.
This is more of an advise than answer. You should avoid using jQuery in Angular. The reason being jQuery modifies the DOM directly and Angular modifies the DOM via an abstraction. You'll run into a lot of trouble doing so.
I couldn't be stuff reading through all that, it's a big mess and doesn't look like you're doing it the proper way anyways and your methods are big and fat and noisy.
If your aim is after scrolling to a certain length then query and display more data then you can try something like:
#HostListener('window:scroll', []) onWindowScroll($event: any) {
// your logic...
}
Then in your template use *ngIfetc...
I'm too very new to angular 2 but this tutorial helped me a lot:
https://www.pluralsight.com/courses/angular-2-getting-started
further to implement infinite scroll use:
https://www.npmjs.com/package/angular2-infinite-scroll.
hope this helps :)

Javascript Callback in for Loop

My problem is that I'm having a Function A which calls at one point another function, let's call it Function B (getChildContent) and needs the return value of Function B in order to proceed. I know that it's because of Javascripts Asynchronous Nature, and i tried to solve it with a callback. But i can't get it work properly.
FunctionA(){
//some Code.....
else {
for(i in clustertitles) {
if(S(text).contains(clustertitles[i])) {
var parent = {};
parent.ClusterName = clustertitles[i];
parent.Functions = [];
var str = '== ' + clustertitles[i] + ' ==\n* ';
str = S(text).between(str,'.').s;
var caps = parseFunctions(str);
for(y in caps) {
//var content = getChildContent(caps[y]);
getChildContent(caps[y], function(content) { //Function call
var child = {};
child.FunctionName = caps[y];
child.Content = [];
child.Content.push(content);
parent.Functions.push(child);
console.log(content);
});
}}}
}
function getChildContent (capname, callback) {
t = capname.replace(' ', '_');
bot.page(t).complete(function (title, text, date) {
var str = S(text).between('== Kurzbeschreibung ==\n* ', '.').s;
if(str === undefined || str === null || str === '') {
throw new Error('Undefined, Null or Empty!');
}
else {
var content = {};
str = parseTitles(str);
content.Owner = str[0];
content.Aim = str[1];
content.What = str[2];
content.Who = str[3];
content.Steps = str[4];
content.Page = 'some URL';
callback(content);
}
});
}
So in Function A I'm trying to call getChildContent from a for-Loop and pass the current string from caps-array. For each String in caps-array getChildContent() makes a http request over a node.js module and retrieves a string. With this string i'm building an object (content) which is needed in Function A to continue. However the 'console.log(content)' in Function A just prints out the object which is created with the last string in caps-array, but for many times. E.G. if caps-array has 5 entries, i get 5 times the object which is created with the last entry of caps-array.
How can i manage the loop/callback to get every time the right object on my console?
Your loop should call another function that preserves the value of y, something like this:
FunctionA(){
//some Code.....
else {
for(i in clustertitles) {
if(S(text).contains(clustertitles[i])) {
var parent = {};
parent.ClusterName = clustertitles[i];
parent.Functions = [];
var str = '== ' + clustertitles[i] + ' ==\n* ';
str = S(text).between(str,'.').s;
var caps = parseFunctions(str);
for(y in caps) {
yourNewFunction (y, caps, parent);
}}}
}
function yourNewFunction (y, caps, parent) {
getChildContent(caps[y], function(content) { //Function call
var child = {};
child.FunctionName = caps[y];
child.Content = [];
child.Content.push(content);
parent.Functions.push(child);
console.log(content);
});
}
function getChildContent (capname, callback) {
t = capname.replace(' ', '_');
bot.page(t).complete(function (title, text, date) {
var str = S(text).between('== Kurzbeschreibung ==\n* ', '.').s;
if(str === undefined || str === null || str === '') {
throw new Error('Undefined, Null or Empty!');
}
else {
var content = {};
str = parseTitles(str);
content.Owner = str[0];
content.Aim = str[1];
content.What = str[2];
content.Who = str[3];
content.Steps = str[4];
content.Page = 'some URL';
callback(content);
}
});
}
There are 2 ways to do so.
Put the loop inside a function, execute your callback after the loop is done. (Problematic if you are doing async call inside the loop.
function doLoopdiloopStuff() {
for() {
}
callback();
}
The other way, the way i prefer looks like this:
for(var i = 0; i < stuff || function(){ /* here's the callback */ }(), false; i++) {
/* do your loop-di-loop */
}
In another example:
for (var index = 0; index < caps.length || function(){ callbackFunction(); /* This is the callback you are calling */ return false;}(); index++) {
var element = caps[index];
// here comes the code of what you want to do with a single element
}

Specified argument was out of the range of valid values. Parameter name: index

I have the following javascript code which must load a termset from sharepoint managed metadata store.
The code was working fine until monday and suddenly stopped working with the error on the title.
I changed the contents of the executequeryasync with just a console.log and I still have the error.
I already debugged line by line the execGetTermIds, and none of the lines there throwed the exception
function GetTermsDataFromTaxonomy(){
//Current Context
var context = SP.ClientContext.get_current();
//Current Taxonomy Session
var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(context);
//Term Stores
var termStores = taxSession.get_termStores();
//Name of the Term Store from which to get the Terms.
var termStore = termStores.getByName("Taxonomy_kl5tZjInn7STsFTzIE7n3Q==");
//GUID of Term Set from which to get the Terms.
var termSet = termStore.getTermSet("31da4bc1-6429-499a-9d5e-be5e18b13c87");
var terms = termSet.getAllTerms();
var list;
var p = execGetTermIDs();
p.done(function(result) {
context.load(terms);
context.executeQueryAsync(function(){
console.log("hola");
},
function(sender,args){
console.log(args.get_message());
});
});
p.fail(function(result) {
// result is a string because that is what we passed to reject()!
var error = result;
console.log(error);
});
}
function sortTermsFromTree (tree) {
if (tree.children.length && tree.term.get_customSortOrder) {
var sortOrder = null;
if (tree.term.get_customSortOrder()) {
sortOrder = tree.term.get_customSortOrder();
}
// If not null, the custom sort order is a string of GUIDs, delimited by a :
if (sortOrder) {
sortOrder = sortOrder.split(':');
tree.children.sort(function (a, b) {
var indexA = sortOrder.indexOf(a.guid);
var indexB = sortOrder.indexOf(b.guid);
if (indexA > indexB) {
return 1;
} else if (indexA < indexB) {
return -1;
}
return 0;
});
}
// If null, terms are just sorted alphabetically
else {
tree.children.sort(function (a, b) {
if (a.title > b.title) {
return 1;
} else if (a.title < b.title) {
return -1;
}
return 0;
});
}
}
for (var i = 0; i < tree.children.length; i++) {
tree.children[i] = sortTermsFromTree(tree.children[i]);
}
return tree;
}
function execGetTermIDs(){
var d = $.Deferred();
var q = "<View><Query><Where></Where></Query></View>";
var context = new SP.ClientContext(siteUrl);
var oList = context.get_web().get_lists().getByTitle('TaxonomyHiddenList');
var camlQuery = SP.CamlQuery.createAllItemsQuery();
var collTermListItem = oList.getItems(camlQuery);
context.load(collTermListItem);
var o = {d: d, collTermListItem:collTermListItem};
context.executeQueryAsync(
Function.createDelegate(o, getTermIDsComplete),
Function.createDelegate(o, failCallback)
);
return d.promise();
}
function getTermIDsComplete()
{
var listItemEnumerator = this.collTermListItem.getEnumerator();
while (listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
termIDs[oListItem.get_fieldValues().Title] = oListItem.get_id();
}
this.d.resolve(termIDs);
}
function failCallback() {
this.d.reject("something bad happened");
}
omg, I found the error, and I cant find an explanation on this, hopefully somebody at Microsoft can tell me.
this line:
var termStore = termStores.getByName("Taxonomy_kl5tZjInn7STsFTzIE7n3Q==");
We noticed the name is now different, it has a different guid, but we as customers cant change that name, so the only reason is Microsoft changed it for us because it was working on monday.
Update: I changed that line with:
termStore = session.getDefaultSiteCollectionTermStore();
to avoid that it happens in the future.

JavaScript - Improve the URL parameter fetching algorithm

I need to get the URL search paramentes in an object, for eg; http://example.com/?a=x&b=y&d#pqr should yield {a:x, b:y, d:1}
Below is the method i used to get this, How can i improve this? any suggessions...
var urlParamKeyVals = new Array();
var pieces = new Array();
var UrlParams = {};
if(window.location.search.length){
var urlSearchString = window.location.search;
if(urlSearchString.charAt(0) == '?'){
urlSearchString = urlSearchString.substr(1);
urlParamKeyVals = urlSearchString.split("&");
}
}
for (var i = 0; i<urlParamKeyVals .length; i++) {
pieces = urlParamKeyVals [i].split("=");
if(pieces.length==1){
UrlParams[pieces[0]]=1;
} else {
UrlParams[pieces[0]]=pieces[1];
}
}
UrlParams;
I've made some time ago a small function for the same purpose:
Edit: To handle empty keys as 1:
function getQueryStringValues (str) {
str = str || window.location.search;
var result = {};
str.replace(/([^?=&]+)(?:[&#]|=([^&#]*))/g, function (match, key, value) {
result[key] = value || 1;
});
return result;
}
getQueryStringValues("http://example.com/?a=x&b=c&d#pqr");
// returns { a="x", b="c", d=1 }
function getParams(q){
var p, reg = /[?&]([^=#&]+)(?:=([^&#]*))?/g, params = {};
while(p = reg.exec(q)){
params[decodeURIComponent(p[1])] = p[2] ? decodeURIComponent(p[2]) : 1;
}
return params;
}
getParams(location.search);
-- edit
I extended the regular expression to match also the &param (no value) and &param= (empty value) cases. In both cases the value 1 is returned. It should also stop extracting on hash (#) character. Decoding values also supported.
jQuery bbq has a nice deparam method if you are trying to look at some very stable code:
http://github.com/cowboy/jquery-bbq/
http://benalman.com/code/projects/jquery-bbq/examples/deparam/
function getObjectFromSearch() {
var search = location.search;
var searchTerms = [];
var obj = {};
if (search !== '') {
search = search.replace(/^\?/,'');
searchTerms = search.split("&");
}
for (var i=0, imax=searchTerms.length; i<imax; i++) {
var ary = searchTerms[i].split("=");
obj[ary[0]] = ary[1];
}
return obj;
}

Categories

Resources