Javascript: Object function causing problems - javascript

I have tag trigger working by setInterval and it alerts when it find the tag in the document. the code did not have any problem until I've got the function into an object for arrangement,
Live examples:
here is an working example without object : http://jsfiddle.net/ae6Xc/4/
here is example with object (with the problem) : http://jsfiddle.net/ae6Xc/10/
here is the "original" working code without the object:
// looking for the special tag than save the
// element in varabile and than alert
(function(){
var win = window ,
doc = document ,
setInter = 'setInterval' ,
clearInter = 'clearInterval' ,
getByTagName = 'getElementsByTagName' ,
KW_pluslike = 'mysite:plugin' ,
zero = 0 ,
element;
// Set 'setInterval' function as trigger
// to target the Special tag.
var trigger = win[setInter](function(){
// Check if such tag exist , if not repeat. When the tag
// has founded , it set the root to the Element var.
if(doc[getByTagName](KW_pluslike)[zero]){
element = doc[getByTagName](KW_pluslike)[zero];
win[clearInter](trigger);
alert("Tag Captured");
}
} , 1000 /5 );
})();
so as i said , i wanted to arrange the things up a little so i took the Trigger function and the Element variable and replaced them into an object like this :
var pluslike = {
element : nul ,
trigger : win[setInter](function(){
if(doc[getByTagName](KW_pluslike)[zero]){
pluslike.element = doc[getByTagName](KW_pluslike)[zero];
win[clearInter](pluslike.trigger);
alert("Tag Captured");
}
} , 1000 /5 );
}
pluslike.trigger;
somehow for some reason it's not working , what causes the problem? i don't know. when it started? when i used the function in object.
thank you in advance.

A semicolon inside the object literal is causing your problem. Fixed code: http://jsfiddle.net/ae6Xc/11/Inside an object literal, properties should be separated by commas. Semicolons are not allowed
Comparison of your code, and the patched code:
trigger : win[setInter](... , 1000 /5 ); //<---Semicolon!!!#!#!#
trigger : win[setInter](... , 1000 /5 ) //<-- Patched, no semicolon

Related

How to have an object key depend on another key in the same object?

I have a very simple function that builds an object and logs it.
One of the keys in the object should be depending on another key.
I think it would be much clearer when I add the code
module.exports = function (information) {
var numObj = {
[-1]: "accepted",
[0]: "fail",
[1]: "success"
}
console.log(numObj)
var ip = require('ip');
var logObj = {
UUID: information.UUID, // get from outside
FN_TIME_STAMP: information.FN_TIME_STAMP, // not sure if necessary
FN_CORRELATION_ID: information.FN_CORRELATION_ID,// get from outside
FN_REF_ID: information.FN_REF_ID, //get from outside
FN_METHOD_NAME: "docToMail", // constant
FN_STATUS_CODE: information.FN_STATUS_CODE, //get from outside
FN_STATUS_DESC: numObj[this.FN_STATUS_CODE], // depends on FN_STATUS_CODE
FN_DOC_ID: information.FN_DOC_ID, //get from outside
FN_USER_NAME: "", // empty for now, probably un-necessary
FN_APP_ID: information.FN_APP_ID, //get from outside
FN_RMT_ADDRS: ip.address(),//ip address of local machine
FN_NUM_OF_RETRIES: information.FN_NUM_OF_RETRIES, // get from outside
FN_FILETYPE: information.FN_FILETYPE, // get from outside
FN_REC_STATE: numObj[this.FN_STATUS_CODE] //depends on FN_STATUS_CODE
}
console.log(logObj)
}
I just want FN_REC_STATE and FN_STATUS_DESC to be a string depending on FN_STATUS CODE.
If its -1 i want the string to be "accepted"
If its 0 i want the string to be "fail"
If its 1 i want the string to be "success"
as it as right now i just get undefined, please help!
Thanks
Assuming that information.FN_STATUS_CODE is either -1, 0 or 1, the following solution should work.
If you change
FN_REC_STATE: numObj[this.FN_STATUS_CODE]
to
FN_REC_STATE: numObj[information.FN_STATUS_CODE]
then it should put the correct value into FN_REC_STATE.
This is because by the time that faulty line is evaluated, this.FN_STATUS_CODE hasn't been defined.
You should also change this for the definition of FN_STATUS_DESC.
Also, it looks like you may be misunderstanding what this refers to in the context of that function. It actually refers to the global object, rather than the logObj object.

D3 append is not a function when using with VueJS and Vuex

I have a html 'div' and I am trying to append another div to it by the following :
var myDiv = d3.select("#container")
myDiv.append("div")
And I get the following error :
myDiv .append is not a function
Any ideas ? I am using Vuex, so I instantiated the variable in the store and trying to set it to the d3 select.
I have put together a codepen that's similar to what I have : https://codepen.io/anon/pen/oMBGmd?editors=1010
const store = new Vuex.Store({
state: {
networkVariables: {
node: "",
data: [1, 2, 3, 4, 5]
},
container: ""
},
getters: {},
mutations: {}
});
console.log("line 33");
console.log(store);
var networkVariables = store.state.networkVariables;
var container = store.state.container;
container = d3.select("#container");
console.log(networkVariables);
networkVariables.node = container
.selectAll(".node")
.data(networkVariables.data);
console.log(networkVariables.node);
networkVariables.nodeEnter = networkVariables.node.append("div");
In your latest codepen, the error you mentioned is coming from the last line, where you are trying to append to the networkVariable.node directly -- without using the enter selection.
It seems to work for me when I change the last line to be:
networkVariables.nodeEnter = networkVariables.node.enter();
networkVariables.nodeEnter.append("div");
Here networkVariables.nodeEnter = networkVariables.node.append("div");, there is no append() in networkVariables.node object. I tried replacing networkVariables.node.append() with networkVariables.node[0].parentNode.append("div"), this seems to work in the snippet. can you try with this change.
The line in the codepen with the error is like #SteveR noticed the last line.
It is not the result of a d3.select() but a d3.selectAll(..).data(...). The array contains 5 empty placeholders and two fields. These are enter and exit, both functions. To convert this to a "selection" result you have to call one of these functions first before you can append().
But in the original question there should be no problem appending if the tag with the given id exists.
The codepen is not similar to the original question/example.

I'm trying to use jquery to create a div containing columns but I can't get my array to format correctly

I have an array that contains dates. and for some reason I can't get it to show on my screen I've been debugging for a few days now and I've tracked it down to a single line, but the line has worked before and I can't figure out what the issue might be.
The array looks like this:
var selectItems =
[ "05-26-2017", "06-02-2017", "06-09-2017",
"06-16-2017", "06-23-2017", "06-30-2017", "07-07-2017", "07-14-2017",
"07-21-2017", "07-28-2017"...];
It's passed as an argument from another function, but that's how it's showing in console.log().
I might be going about this the wrong way, maybe even a lot further around then I need to but this is what I've come up with:
1. function setTHead(selectItems) {
2 var formatString;
3. for (var x = 0; x < 12; x++) {
4. formatString = selectItems[x].replace(/[^0-9/-]/g, "").toString();
5. console.log(selectItems);
6. $('#datTab').append("<div id='col" + x + "' class='column'>'" + formatString + "'</div>");
7. }
8. }
the array up top is what's showing from the console.log 5 lines down.
the sixth line is what is seeming to give me issues. Nothing is put on the page at all.
I'm getting a console error saying:
jQuery.Deferred exception: selectItems is undefined setTHead#http://localhost/mySite/script.js:136:9
startUp2#http://localhost/mySite/script.js:146:5
#http://localhost/mySite/table.php:19:9
mightThrow#http://localhost/mySite/lib/jquery.js:3586:52
resolve/</process<#http://localhost/mySite/lib/jquery.js:3654:49
setTimeout handler*resolve/<#http://localhost/mySite/lib/jquery.js:3692:37
fire#http://localhost/mySite/lib/jquery.js:3320:30
fireWith#http://localhost/mySite/lib/jquery.js:3450:29
fire#http://localhost/mySite/lib/jquery.js:3458:21
fire#http://localhost/mySite/lib/jquery.js:3320:30
fireWith#http://localhost/mySite/lib/jquery.js:3450:29
ready#http://localhost/mySite/lib/jquery.js:3923:13
completed#http://localhost/mySite/lib/jquery.js:3933:9
EventListener.handleEvent*#http://localhost/mySite/lib/jquery.js:3949:9
#http://localhost/mySite/lib/jquery.js:39:9
#http://localhost/mySite/lib/jquery.js:17:3
undefined
followed by:
TypeError: selectItems is undefined
and thats pointing to line 6.
if anyone has any advice I would be very much appreciative. Thank you in advance.
EDIT: A little more code:
function startTblView(defSel) {
if (defSel === true) {
setCookie('defSel', true, 7);
} else{
setCookie('defSel', false, 7);
}
saveSelected();
window.open('table.php', '_self');
defSel = getCookie('defSel');
if (defSel) {
selectItems = getDefDates();
}else {
selectItems = reGetSelected();
}
setTHead(selectItems);
}
defSel, is a boolean passed from my last page stating whether I'm doing a default view or a custom view, the custom view is passed from saveSelected();
saveSelected is a function for just saving the selected global value as a cookie so I can pull it out on the next page.
getDefDates pulls the default values for the array
reGetSelected, gets the selected array from the cookie.
I apologize for wonky naming conventions. I'm the only one working on this site and I'm just making sure the names don't overlap.
You can do this :
HTML code
<div id="datTab"></div>
JS code
var selectItems =
[ "05-26-2017", "06-02-2017", "06-09-2017",
"06-16-2017", "06-23-2017", "06-30-2017", "07-07-2017", "07-14-2017",
"07-21-2017", "07-28-2017"];
function setTHead(selectItems) {
var formatString;
$.each( selectItems, function( index, value ){
formatString = value.replace(/[^0-9/-]/g, "").toString();
$('#datTab').append("<div id='col" + index + "' class='column'>'" + value + "'</div>");
});
};
You can use $.each, its better than 'for' with javascript.
The .each() method is designed to make DOM looping constructs concise
and less error-prone. When called it iterates over the DOM elements
that are part of the jQuery object. Each time the callback runs, it is
passed the current loop iteration, beginning from 0. More importantly,
the callback is fired in the context of the current DOM element, so
the keyword this refers to the element.
I did a JsFiddle
Here.

adding properties to an object

I wrote this code and it`s simple , i have an empty object which will contain some other objects as properties , but the object stays empty and don`t add the needed properties ..
let buildProfileClientValidator = function(form , rules){
let elements = {};
function init(){
//Some code that works fine
addElement(elementName , elementType);
addElement(elementName , elementType);
//the elements object should now have some other objects as properties
//but it`s empty !!!!
console.log(elements);
}
function addElement(elementName , elementType){
//this condition works fine
if( !elementExist(elementName) ){
//console.log(elementName , elementType); also works fine -> the values of elementName , elementType are present
elements[elementName] = {
type : elementType,
value : '',
rules : (rules[elementName] == undefined) ? '' : rules[elementName].split('|')
};
}
}
}
so what i`m missing ?!
After examining your code, but not knowing how buildProfileClientValidator gets called (and specifically what the rules parameter is), I can trace the problem to this line:
(rules[elementName] === undefined) ? '' : rules[elementName].split('|')
I have modified your code (to make it testable) in the following fiddle (https://jsfiddle.net/hssbsL19/40/) and when I replace that line with a static value, the code works.

JQuery: How to cache DOM?

I used Firefug to profile my web application and found that the following function is called, and needs to be called, literally hundreds of times per user visit. So I want to optimize it since Firebug says it uses the most resources/times.
function highlightChildDiv(parentDiv) {
/* find the closest (hlisting) home listing to the middle of the scrollwindow & highlight */
var scrollElemPos = parentDiv.offset();
var highlightDiv = $(document.elementFromPoint(
scrollElemPos.left + parentDiv.width() / 2,
scrollElemPos.top + parentDiv.height() / 2)
).closest('#parentDiv div.childClass');
if (highlightDiv.hasClass("HighlightRow")) {
return; // if the div is already highlighted, return
} else {
$('#parentDiv div.childClass').removeClass("HighlightRow");
highlightDiv.addClass('HighlightRow');
}
}
Seems to me that one of the most un-optimized statements is .closest('#parentDiv div.childClass');, but I'm sure there is other things to improve.
Question: Does anyone have any JQuery performance tips on how I can optimize the code above given that this function is run literally hundreds of times per user visit.
First thought, eliminate the dead statement in the if clause.
if (!highlightDiv.hasClass("HighlightRow")) {
$('#parentDiv div.childClass').removeClass("HighlightRow");
highlightDiv.addClass('HighlightRow');
}
In the selector #parentDiv div.childClass, can you guarantee that div will be a direct descendent of #parentDiv? In which case:
.closest('#parentDiv>div.childClass');
and
$('#parentDiv>div.childClass')
You already have parentDiv. I'm guessing this is a DOM object, so you may be able to do the following:
$(parentDiv).children("div.childClass")
Just hide the DIV that is currently highlighted:
$('#parentDiv div.HighlightRow').removeClass("HighlightRow");
My guess is this is the most unoptimized line:
$('#parentDiv div.childClass').removeClass("HighlightRow");
You should profile it to make sure (create a date object outside the call and output the getTime() value before and after each call).
Here you are asking jQuery to iterate over all DOM elements that match that selector and remove the class. If there are 1000 rows, jQuery will need to interogate each one to see if it needs to remove a class. Ugh. Here it is with that lookup removed:
// namespace scoped cache
var Hash_$_Cache = {
$parentDiv : $('#parentDiv'),
$tgt_row : $([]) // empty jq object to start
};
// find the closest (hlisting) home listing to the middle of
// the scrollwindow and highlight
//
var highlightChildDiv = function (parentDiv){
var
scrollElemPos = parentDiv.offset(),
$tgt_row
;
$tgt_row = $(document.elementFromPoint(
scrollElemPos.left + parentDiv.width() / 2,
scrollElemPos.top + parentDiv.height() / 2)
).closest('#parentDiv div.childClass')
;
// bail if row is already highlighted
if ($tgt_row.hasClass('HighlightRow')){ return; }
Hash_$_Cache.$tgt_row.removeClass('HighlightRow');
$tgt_row.addClass('HighlightRow');
// save highlighted row for later
Hash_$_Cache.$tgt_row = $tgt_row; // store new row in cache
};
Hope that helps!
I prefer to use the following methodology:
https://gist.github.com/3841424#file-domcache-js
Or, you may replace the DOM object with a method in this implementation:
var myNS = {
myEventHandler: function(event){
this.DOM.$el.doSomething();
},
cacheDOM: function(){
return {
$el: $("#matrix")
};
},
initialize: function(){
this.DOM = this.cacheDOM();
}
};

Categories

Resources