I am adding a Google Analytics tracking event to nav menu links, with this code:
(function ($) {
"use strict";
$(function () {
$("body").on('click', '.menu-item a', function () {
var trackingCode = $(this).next(".ga-tracking");
if (trackingCode.length > 0) {
var t1 = trackingCode.data("tracking-1"),
t2 = trackingCode.data("tracking-2"),
t3 = trackingCode.data("tracking-3"),
t4 = trackingCode.data("tracking-4"),
params = "'" + t1 + "','" + t2 + "','" + t3 + "'";
_gaq.push([params]);
}
});
});
}(jQuery));
you can see it working here: http://paulwp.com/blog/
to trigger the code, click on the Blog link in the top black bar.
This is the error I get:
_gaq.push processing "'_trackEvent','Store_Outbound','Link_Click'" for args: "[]":
Called method "'_trackEvent','Store_Outbound','Link_Click'" threw exception.TypeError: Cannot call method 'apply' of undefined
whereas it should give something like this:
_gaq.push processing "_trackEvent" for args: "[Store_Outbound,Link_Click]":
guess it's the way I build the parameters with the variables that's causing the issue
You are passing the values wrong. This is effectively what you are doing:
_gaq.push(["a,b,c"]);
That is an array with a single element.
This is what it should look like:
_gaq.push(["a","b","c"]);
This is an array with multiple elements.
So basically you need to do
params = [t1,t2,t3];
_gaq.push(params);
or just put them directly in:
_gaq.push([t1,t2,t3]);
Related
I would like to modify the Javascript that is downloaded as part of a web page.
I have this page:
https://discussions.apple.com/thread/7629335
I would like to modify the function jspaginate.init. I've gotten this far:
console.log(window.jspaginate)
Object { data: Object, loading: false, init: jspaginate.init(), update: jspaginate.update(), pushState: jspaginate.pushState(), loadingSequence: jspaginate.loadingSequence(), removeLoading: jspaginate.removeLoading(), updateUI: jspaginate.updateUI(), getData: jspaginate.getData() }
undefined
console.log(window.jspaginate["init"])
function jspaginate.init()
console.log(window.jspaginate["init"].toString())
function (action, last){
var view = this,
target, current;
... clipped ...
background:
This page includes lots of javascript. The function jspaginate is download from the site server. Nevertheless, I need to change the function jspaginate. I do not have access to the server. I want to change my copy of jspaginate. I know that I need to change the function every time it is downloaded.
I'm using GreaseMonkey to insert some javascript.
Just override the init function with its new definition, like below:
window.jspaginate.init = function() {
console.log('there you go');
}
Here is the code I used. Since I had converted jspaginate.init to a string and modified the string, I had to convert the string to a function. I did the conversion via the eval function.
var debug = 1;
/* Get the string of the function to change */
var stringed = jspaginate["init"].toString();
if ( debug ) console.log ("--> cloneGotoChange: \n" + stringed);
/* Place the added code as the last statement in the function jspaginate["init"]
Find the function closing } */
position = stringed.lastIndexOf("}");
/* Change the downloaded javascript */
var newCode = stringed.substr(0, position)
+ " console.log (\"--> before \" ); cloneGotoUpate(); console.log (\"--> after \" ); "
+ stringed.substr(position);
/* Inject the changed code
need to use the eval function to make a function assignment instead of a string assignment */
eval( 'jspaginate["init"] =' + newCode);
if ( debug ) console.log (console.log(window.jspaginate["init"].toString()));
I'm using Tizen's Wearable SDK to create a watch face, and while I am able to retrieve the Bluetooth's power state by using blueAdapter = tizen.bluetooth.getDefaultAdapter(); and bluetoothPowered = blueAdapter.powered;, I'd rather use a Bluetooth listener instead of constantly calling blueAdapter.powered.
The problem I'm having is that although I did a straight forward copy and paste of the sample code (although I did change the adapter's name, see below) from Tizen's Bluetooth API webpage, I'm getting the following error: 'undefined' is not a function (evaluating 'blueAdapter.setChangeListener(changeListener)').
This is the code I am using:
var blueAdapter = tizen.bluetooth.getDefaultAdapter();
var changeListener = {
onstatechanged: function(powered) {
console.log ("Power state is changed into: " + powered);
},
onnamechanged: function( name) {
console.log("Name is changed to: " + name);
},
onvisibilitychanged: function(visible) {
console.log("Visibility is changed into: " + visible);
}
};
blueAdapter.setChangeListener(changeListener);
Not sure if it helps, but I am using the following the privileges:
http://tizen.org/privilege/bluetooth.admin
http://tizen.org/privilege/bluetooth.gap
Any help would be appreciated.
Although it's been a while now, have you tried changing the syntax like below?
function changeListener(handler) {
handler.onstatechanged = function(powered) {
console.log ("Power state is changed into: " + powered);
}
handler.onnamechanged = function(name) {
console.log("Name is changed to: " + name);
}
handler.onvisibilitychanged = function(visible) {
console.log("Visibility is changed into: " + visible);
}
};
this replaces your listener object by a function, which should then declare the needed functions in the listener. It is just an idea, i did not test it yet.
first off : I'm new to node, and a relative programming beginner.
I'm trying to create a small web app with Express, whose only goal is to fetch and reformat data from a website that doesn't have an open API.
To do so, I've decided to learn about scraping, and that brought me to Cheerio and Request.
I'm using reddit as an example, to learn on. The end goal in this example is to gather the name and href of the posts on the front page as well as the url leading to the comments, then to go on that page to scrape the number of comments.
What follows is the route that is called on a GET request to / (please excuse the variable names, and the comments/console.logs, I got frustrated) :
/*
* GET home page.
*/
exports.index = function(req, res){
var request = require('request')
, cheerio =require('cheerio')
, mainArr = []
, test = "test"
, uI
, commentURL;
function first() {
request("http://www.reddit.com", function(err, resp, body) {
if (!err && resp.statusCode == 200) {
var $ = cheerio.load(body);
$('.thing', '#siteTable').each(function(){
var url = $('a.title', this).attr('href')
, title = $('a.title', this).html()
, commentsLink = $('a.comments', this).attr('href')
, arr = [];
arr.push(title);
arr.push(url);
arr.push(commentsLink);
mainArr.push(arr);
});
second();
};
});
}
function second() {
for (i = mainArr.length - 1; i >= 0; i--) {
uI = mainArr[i].length - 1;
commentURL = mainArr[i][uI];
console.log(commentURL + ", " + uI + ", " + i);
var foo = commentURL;
request(foo, function(err, resp, body) {
console.log("what the shit");
// var $ = cheerio.load(body);
// console.log(mainArr.length + ", " + commentURL + ", " + i + ", " + uI);
// var test = $('span.title', 'div.content').html();
console.log(test + ", "+ foo + ", " + commentURL + ", " + i + ", " + uI);
// mainArr[1][2] = test;
});
};
if (i<=0) {
res.render('index', {title: test});
};
}
first();
};
The function first(); works as intended. It puts the title, the href and url to the comments in an array, then pushes that array in a master array containing those data points for all of the posts on the front page. It then calls the function second();
Said function's goal is to loop through the master array (mainArr[]), then select all of the urls leading to comments (mainArr[i][uI]) and launch a request() with that url as first parameter.
The loop works, but during the second call of request() inside the second() function, everything breaks down. The variable i gets set permanently at -1, and commentURL (the variable that is set to the URL of the comments of the current post), is defined permanently as the first url in arrMain[]. There are also weird behaviors with arrMain.length. Depending on where I place it, it tells me that arrMain is undefined.
I have a feeling that I'm missing something obvious (probably to do with asynchronicity), but for the life of me, I can't find it.
I would be really greatful for any suggestions!
You are correct about your guess, it's the infamous "Javascript loop Gotcha". See here, for example, for an explanation:
Javascript infamous Loop issue?
Besides that, it seems that only your debug prints are affected. The commented code regarding var test ought to work.
Finally, the kind of language is frowned upon in SO, you would do well to take 2 minutes and change your variable names in this post.
Following the answer in this stackoverflow question, I am trying to run the following code. But the myfunction takes only one google visualization event. So Is the following code is valid? Or how to handle multiple statechange google visualization events in a single function?
var categoryPicker1, categoryPicker2;
function drawVisualization() {
// etc.
categoryPicker1 = // etc...
categoryPicker2 = // etc...
// Register to hear state changes.
google.visualization.events.addListener(categoryPicker1, 'statechange', myfunction);
google.visualization.events.addListener(categoryPicker2, 'statechange', myfunction);
// etc.
}
function myfunction() {
var whereClauses = [];
if (categorypicker1) {
whereClauses.push("something1 = '" + document.getElementsByClassName('goog-inline-block goog-menu-button-caption')[0].innerHTML + "'")
}
if (categorypicker2) {
whereClauses.push("something2 = '" + document.getElementsByClassName('goog-inline-block goog-menu-button-caption')[1].innerHTML + "'")
}
whereClause = whereClauses.join(" AND ");
// do something....
}
Not really clear from your question, but I assume you're building the SQL query to your database from the selected items in the CategoryPicker. Despite being an EXTREMELY bad/dangerous thing to do (building SQL client side, and sending it to a server), this should be possible by just grabbing the selectedItems from your CategoryPicker, and joining them with " AND ". Like:
values = categoryPicker1.getState().selectedValues;
values = values.concat(categoryPicker2.getState().selectedValues);
var args = values.map(function(_) { return "'" + _ + "'"; });
console.log(args.join(" AND "));
I wouldn't do this if I were you. I would pass the arguments up to the server, and remap them there (after appropriately filtering them, etc). Again this is very dangerous.
I am developing a WebPart in SharePoint,and I need to draw something in my WebPart using excanvas.js.But sometimes it shows nothing.The error message is:
Object doesn't support property or method 'getContext'
When I debug it,it breaks at here:
var ctxBg = document.getElementById(backgroundId).getContext("2d");
The "backgroundId" is the id of one canvas element.
This error happens not every times,just sometimes,so I think if my js function is executed before the excanvas.js is loaded.I register the excanvas.js with the code:
this.Page.ClientScript.RegisterClientScriptInclude("ExCanvasJs", "wpresources/MyWebPart/js/excanvas.js");
So how to ensure my function is executed after the excanvas.js is loaded?Or I'm wrong at this problem?Would you give me your advice?
my js function:
function DrawMeter(meter, contextCollection) {
var backgroundId = meter.meterbackground;
var pointerId = meter.meterpointer;
var containerId = meter.metercontainer;
if (contextCollection != null && contextCollection.length > 0) {
for (var i = 0; i < contextCollection.length; i++) {
DrawSingleMeter(backgroundId + "_" + i, pointerId + "_" + i, containerId + "_" + i, contextCollection[i]);
}
}
function DrawSingleMeter(backgroundId, pointerId, containerId, context) {
var ctxBg = document.getElementById(backgroundId).getContext("2d");
var ctxPointer = document.getElementById(pointerId).getContext("2d");
drawing...
}
you need to put it into a page ready handler. otherwise at the time the javascript is executed the element might not be available yet.
consider using jquery or another js library for this, if you can't use it here's a link on how to use the native js version of the onload event