I'm using the following for event tracking:
var dataTrack = e.split(','); // split by comma
if (dataTrack !== undefined) {
var action = dataTrack[0];
var values = {};
values[dataTrack[1]] = dataTrack[2];
mpq.track(action, values);
}
How can I trim dataTrack[0], dataTrack[1], dataTrack[2] in a way where if any of the dataTrack vars are empty it won't break? 1 & 2 are optional...
Thanks
A common idiom in JavaScript is to provide default values like so:
// default to the empty string
var dataTrack0 = dataTrack[0] || '',
dataTrack1 = dataTrack[1] || '',
dataTrack2 = dataTrack[2] || '';
...though I think a better solution, in this case, might be to check the length of the array.
You probably want to use the length property for the array.
var dataTrack = e.split(','); // split by comma
if (dataTrack !== undefined) {
var action = dataTrack[0];
var values = {};
if(dataTrack.length > 2) {
values[dataTrack[1]] = dataTrack[2];
}
mpq.track(action, values);
}
You could add extra validation to check that dataTrack[ 1] has a length > 0 if it is possible that someone would pass "value1,,value3".
Couldn't you just check to make sure they are not empty? Also you could use the ternary operator to have a default value if they are empty (i.e. action == undefined ? "Default" : datatrack[0];).
Replace
values[dataTrack[1]] = dataTrack[2];
with
if(dataTrack.length > 2){
values[dataTrack[1]] = dataTrack[2];
}
Related
How can I add an "else" statement to the following dictionary with key/value pairs to handle any sort of ambiguity?
var inputArr = input.match(/[\d.]+/g).map(Number);
var inputAnswer = ""
inputArr.forEach(function(element, index){
var lookUp = {
"1":"611"
"2":"612"
"3":"613"
"":""
};
inputAnswer = lookUp[element];
}
return inputAnswer
});
As you can see, the key/value pairs are only programmed to handle "1","2","3", and "". How can I add another value to it which would return blank string ("") if it is passed any other value? Just want it to be dynamically set up to handle any sort of data. Thanks!
Using a simple ternary, combined with hasOwnProperty will let you do what you want.
Note: using a simple || check may not give the desired results, as it will return '' if falsey value is set in the lookUp object. For a demo of why / how this may not do what you expect, see this fiddle
var inputArr = input.match(/[\d.]+/g).map(Number);
var inputAnswer = ""
inputArr.forEach(function(element, index) {
var lookUp = {
"1":"611"
"2":"612"
"3":"613"
"":""
};
// If a defined value exists, return it, otherwise ''
inputAnswer = ( lookUp.hasOwnProperty(element) ) ? lookUp[element] : '';
}
return inputAnswer
});
I've read some question but I still can't figure out how to do it
I have a url example.com/event/14aD9Uxp?p=10
Here I want to get the 14aD9Uxp and the value of p
I've tried using split('/'+'?p=') but it doesn't work
I want to use regex but I dont really understand how to use it
var URL='example.com/event/14aD9Uxp?p=10';
var arr=URL.split('/');//arr[0]='example.com'
//arr[1]='event'
//arr[2]='14aD9Uxp?p=10'
var parameter=arr[arr.length-1].split('?');//parameter[0]='14aD9Uxp'
//parameter[1]='p=10'
var p_value=parameter[1].split('=')[1];//p_value='10';
I've created a generalized function (restricted in some ways) that will return the GET value given the parameter. However this function will only work correctly provided that you do not Rewrite the URL or modify the URL GET SYNTAX.
//Suppose this is your URL "example.com/event/14aD9Uxp?p=10";
function GET(variable) {
var str = window.location.href;
str = str.split("/");
// str = [example.com, event, 14aD9Uxp?p=10]
//Get last item from array because this is usually where the GET parameter is located, then split with "?"
str = str[str.length - 1].split("?");
// str[str.length - 1] = "14aD9Uxp?p=10"
// str[str.length - 1].split("?") = [14aD9Uxp, p=10]
// If there is more than 1 GET parameter, they usually connected with Ampersand symbol (&). Assuming there is more, we need to split this into another array
str = str[1].split("&");
// Suppose this is your URL: example.com/event/14aD9Uxp?p=10&q=112&r=119
// str = [p=10, q=112, r=119]
// If there is only 1 GET parameter, this split() function will not "split" anything
//Remember, there might only be 1 GET Parameter, so lets check length of the array to be sure.
if (str.length > 1) {
// This is the case where there is more than 1 parameter, so we loop over the array and filter out the variable requested
for (var i = 0; i < str.length; i++) {
// For each "p=10" etc. split the equal sign
var param_full_str = str[i].split("=");
// param_full_str = [p, 10]
//Check if the first item in the array (your GET parameter) is equal to the parameter requested
if (param_full_str[0] == variable) {
// If it is equal, return the second item in the array, your GET parameter VALUE
return param_full_str[1];
}
}
} else {
// This is the case where there is ONLY 1 GET parameter. First convert it to a String Type because Javascript decided that str was no longer a String
// Now split it with the equal sign.
str = str.toString().split("=");
return str[1];
}
}
document.write(GET("p"));
function $_GET(param) {
var vars = {};
window.location.href.replace(
/[?&]+([^=&]+)=?([^&]*)?/gi, // regexp
function( m, key, value ) { // callback
vars[key] = value !== undefined ? value : '';
}
);
if ( param ) {
return vars[param] ? vars[param] : null;
}
return vars;
}
I have collected this from here:
http://www.creativejuiz.fr/blog/javascript/recuperer-parametres-get-url-javascript
It works great.
To use it just grab your parameter like:
var id = $_GET('id');
const url = new URL('http://example.com/event/14aD9Uxp?p=10');
const [,, eventId ] = url.pathname.split('/');
const p = url.searchParams.get('p');
Browser support:
https://caniuse.com/#feat=url
https://caniuse.com/#feat=urlsearchparams
Simple no-regex way
var s = "example.com/event/14aD9Uxp?p=10";
var splitByForwardSlash = s.split('/');
// To get 14aD9Uxp
splitByForwardSlash[splitByForwardSlash.length-1]
// To get p=10
splitByForwardSlash[splitByForwardSlash.length-1].split('?')[1]
I think you know how to go from here :-)
So , I want to test many conditions, for different values... right now is just a bunch of if,else statements...
But it looks ugly im sure there must be a better way...
any ideas ?
Im thinking maybe with loops but or putting all vars in an array, but I cant figure out how..
Thx!
var dataObject = {}
if (newState.playerId){
dataObject["filter[player_id]"] = newState.playerId
}else{
dataObject["filter[player_id]"] = this.state.playerId
}
if (newState.pageLimit){
dataObject ["page[limit]"] = newState.pageLimit
}else{
dataObject["page[limit]"] = this.state.pageLimit
}
if (newState.timeFrom){
dataObject["time[from]"] = newState.timeFrom
}else{
dataObject["time[from]"] = this.state.timeFrom
}
if (newState.timeTo){
dataObject["time[to]"] = newState.timeTo
}else{
dataObject["time[to]"] = this.state.timeTo
}
if (newState.gameId){
dataObject["filter[game_id]"] = newState.gameId
}else{
dataObject["filter[game_id]"] = this.state.gameId
}
if (newState.customerId){
dataObject["filter[customer_id]"] = newState.customerId
}else{
dataObject["filter[customer_id]"] = this.state.customerId
}
if (newState.currency){
dataObject["filter[currency]"] = newState.currency
}else{
dataObject["filter[currency]"] = this.state.currency
}
if (newState.variant){
dataObject["filter[locale]"] = newState.locale
}else{
dataObject["filter[locale]"] = this.state.locale
}
if (newState.variant){
dataObject["filter[demo]"] = newState.demo
}else{
dataObject["filter[demo]"] = this.state.demo
}
Use the or (||) operator taking benefit of the short circuit evaluation, e.g.
dataObject["filter[player_id]"] = newState.playerId || this.state.playerId
Reducing your condition
First, you can use javascript's || operator and change:
if (newState.playerId){
dataObject["filter[player_id]"] = newState.playerId
}else{
dataObject["filter[player_id]"] = this.state.playerId
}
To the much reduced:
dataObject["filter[player_id]"] = newState.playerId || this.state.playerId;
DRY up your code
You can use an array of properties:
var propertyList = ["playerId", "pageLimit", "timeFrom" /* etc. */]
Because object properties can be referenced using square brackets you can loop through them like this:
propertyList.forEach(function(property){
dataObject[property] = newState[property] || this.state[property]
});
Disclaimer: This solution is not taking into account your embedded objects (like "filter") and the slight variations in your naming schemes (like "player_id" vs "playerId").
Three solutions occur to me:
Use consistent naming conventions
In other words in the dataObject that you build have the same naming pattern as your state object.
Use a helper function
Convert the names in your for loop using some kind of consistent pattern that changes playerId to player_id when those kinds of changes need to be done. (this will still not work if you plan to use "filter", "time" or "page".
Use objects/arrays (as in #ssube's solution)
You could also use an array or an object to translate your property names between objects. I won't give you an example - #ssube has done so already.
You have a recurring pattern here:
if (newState[srcField]) {
dataObject[destField] = newState[srcField]
} else {
dataObject[destField] = this.state[srcField]
}
Thanks to JS' handling of the OR operator, you can simplify that to:
dataObject[destField] = newState[srcField] || this.state[srcField];
Since you have the field names, you can set up a loop like:
var dataObject = {};
var fields = [
['playerId', 'filter[player_id]'],
['pageLimit', 'page[limit]']
];
fields.forEach(function (field) {
var src = field[0], dest = field[1];
dataObject[dest] = newState[src] || this.state[src];
});
and voila, the fields will be copied across with appropriate renaming.
var dataObject = {};
dataObject['filter[player_id]'] = newState.playerId || this.state.playerId;
dataObject['filter[game_id]'] = newState.gameId || this.state.gameId;
dataObject['filter[customer_id]'] = newState.customerId || this.state.customerId;
dataObject['filter[currency]'] = newState.currency || this.state.currency;
dataObject['filter[locale]'] = newState.variant ? newState.locale : this.state.locale;
dataObject['filter[demo]'] = newState.variant ? newState.demo: this.state.demo;
dataObject['page[limit]'] = newState.pageLimit || this.state.pageLimit;
dataObject['time[from]'] = newState.timeFrom || this.state.timeFrom;
dataObject['time[to]'] = newState.timeTo || this.state.timeTo;
Grab the substring:
var hash = document.location.hash;
// create an object to act like a dictionary to store each value indexed by its key
var partDic = {};
// remove the leading "#" and split into parts
var parts = hash.substring(1).split('&');
// If you just want the first value, whatever it is, use this.
// But be aware it's a URL so can be set to anything in any order, so this makes little sense
// var string = parts[0].split('=')[1];
// build the dictionary from each part
$.each(parts, function(i, v) {
// do the "=" split now
var arr = v.split("=");
// decode to turn "%5B" back into "[" etc
var key = decodeURIComponent(arr[0]);
var value = decodeURIComponent(arr[1]);
// store in our "dictionary" object
partDic[key] = value;
});
// Set a delay to wait for content to fully load
setTimeout( function() {
var ag = partDic["comboFilters[Agencies]"].substring(1);
$('.Agency .dropdown-toggle').html(ag).append(' <span class="caret"></span>');
var cl = partDic["comboFilters[Clients]"].substring(1);
$('.Client .dropdown-toggle').html(cl).append(' <span class="caret"></span>');
var yr = partDic["comboFilters[Years]"].substring(1).slice(1);
$('.Year .dropdown-toggle').html(yr).append(' <span class="caret"></span>');
}, 1000);
But if there is not a substring, I am getting:
Uncaught TypeError: Cannot read property 'substring' of undefined
Suggested answer in another question
var cl = (partDic["comboFilters[Clients]"] && partDic["comboFilters[Clients]"].length>0)?partDic["comboFilters[Clients]"].substring(1):'';
But I still get the same error
You can be defensive and check if a key exists before using it:
if("comboFilters[Agencies]" in partDic) {
var ag = partDic["comboFilters[Agencies]"].substring(1);
$('.Agency .dropdown-toggle').html(ag).append(' <span class="caret"></span>');
}
or just safeguard it with an empty string:
var ag = (partDic["comboFilters[Agencies]"] || "").substring(1);
Maybe try with things like:
var parts = (hash && hash.substring(1).split('&')) || [];
You can try to check it's type:
var cl = (typeof partDic["comboFilters[Clients]"] === 'string')?partDic["comboFilters[Clients]"].substring(1):'';
Note, that you should add this check for all your variables: ag, cl, yr
You can check one condition before using substring method..
if((!hash) || (!hash.substring(1)){
return false;
}
I am having trouble running this code, any one has idea what could be wrong with it?
please check line # 4
for(i=0; i<document.anyForm.elements.length; i++) {
element_type = document.anyForm.elements[i].type;
if(element_type.toUpperCase() == "TEXT" || element_type.toUpperCase() == "TEXTAREA") {
var parse(document.anyForm.elements[i].name) = document.anyForm.elements[i].value;
}
}
var parse(document.anyForm.elements[i].name)
This is incorrect. you either need to define a variable or invoke a function var before the function invocation is invalid.
EDIT:
you can use an object to store the name:value pairs:
var obj = {}; // before loop
//in loop
obj[document.anyForm.elements[i].name] = document.anyForm.elements[i].value;