Recently we upgraded to universal analytics which appears to all be working. I have been trying to capture the clientID to a js variable via the following code:
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-REMOVED', 'xxxx.xxx');
ga('require', 'linkid', 'linkid.js');
ga('send', 'pageview');
ga(function(tracker) {
var clientId = tracker.get('clientId');
});
</script>
To prove the variable clientID is being captured I try and write it to the page using the following code:
<script>
document.write(clientId);
</script>
Which writes nothing to the page.
I have browsed this site and others but can not figure what i am missing. I feel like i'm overlooking something blindingly obvious. Any help much appreciated.
Ultimately i will be writing the variable to a form field to process offline steps occuring in a 3rd party system.
In your code, the variable clientId is declared inside a function. Hence, 'clientId' does not have a global scope. Its value is not accessible outside of the function. Need to assign the value from tracker.get('clientId') to a global variable if you need to use it later. See http://learn.jquery.com/javascript-101/scope/
Calling the following does work on my page:
ga(function(tracker) { alert(tracker.get('clientId'));})
I am doing exactly the same thing as you but instead of writing it to a page, I am alerting it. Maybe document.write is not working for you as expected?
If the code you posted is same as the one you are using, The reason it is not working is because document.write runs before the callback is called. remember that everything that you pass into ga() is asynchronous.
Related
Giving Svelte/Sapper a look and am curious what the right way to add something like Google Sign-In for Websites to my app.
I have everything working from the example code they give you from the site above, but I've done it by adding the onsuccess "onSignIn" function to the template.html file which doesn't seem like the right way to do this.
Inside src/routes/template.html
<script src="https://apis.google.com/js/platform.js" async defer></script>
<script>
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
console.log("ID: " + profile.getId());
}
</script>
Inside src/components/Nav.svelte
<div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
The code above works fine because onSignIn has access to window, but it seems like I should be able to add this to the Nav component where the button itself lives. Is there a preferred way to handle something like this?
If anyone is looking for something similar, I found this git repo that I was able to get started and modify to suit my needs github.com/beyonk-adventures/svelte-social-auth.
I have been trying to use analytics.js to track my average page load time under Behaviour --> Site Speed --> Page Timings. I am using (as already mentioned) analytics.js i.e Universal Analytics instead of ga.js i.e Classic Analytics since that is what is recommended in the documentations. I am tracking it for my localhost application
My issue is that the average page load time is not being reflected at all, although 'pageview' is reflected properly. It shows a zero for all pages across the application.
This is the script that I included for the analytics
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXX-Y', {'cookieDomain': 'none', 'siteSpeedSampleRate': 100}); //cookie domain is none since I am testing in localhost -- siteSpeedSampleRate set to 100 is the code I included for tracking page load time
ga('send', 'pageview');
ga('send', { //Code to send UserTiming
'hitType': 'event',
'timingCategory': 'category',
'timingVar': 'lookup',
'timingValue': '123',
'timingLabel': 'myUserTime'
});
</script>
As mentioned in the comments, cookie domain is none since I am testing in localhost and siteSpeedSampleRate set to 100 is the code I included for tracking page load time as suggested in the documentation. I am also sending the User Timing as suggested in the documentation of analytics.js User Timings
My questions are :
What should I do to get the average page load time of each page. I searched a lot and am not being to get the proper javascript snippet.
I included the user timing javascript snippet a two days later than I included the 'pageview'. So is it like it will take some time to get reflected in the analytics dashboard? If so, how much time.
Please help me get a clearer idea. Thanks in advance.!
This answer here helped me solve my problem. I just reemoved the cookieDomain here and changed the line to this
ga('create', 'UA-XXXXXX-Y', {'siteSpeedSampleRate': 100});
I have a login system that works for most people (on Chrome, Android devices, IE8, Firefox, etc), but it seems not to work for people with Z10s or iPhone 5s. I don't have access to these devices so it's difficult to test, so I wanted to ask whether I was setting up everything properly.
It's an AngularJS app, using hello.js for OAuth, and bootstrap-social and font-awesome for the sign in buttons.
To insert hello into Angular, in app.js I include:
var app = angular
.module('myapp', [
'ui.bootstrap',
'ui.router',
'hello',
])
...
.run([..., 'hello', ..., function(..., hello, ...) {
...
hello.init(...);
...
}]);
...
var helloApp = angular.module('hello', []);
helloApp.factory('hello', function() {
return window.hello; // Assumes hello has been loaded
});
Then, in my loginCtrl, I inject it with
angular.module('myapp').controller('loginCtrl', [..., 'hello', ...,
function(..., hello, $location, ...) {
...
$scope.doLogin = function(network) {
console.log('Calling hello ' + network);
hello.login(network);
};
...
}]);
And in my view, I have
<button id="facebookLogin" class="btn btn-social btn-facebook" ng-click="doLogin('facebook')">
<span class="fa fa-facebook pull-left"></span> <span>Sign in with Facebook</span>
</button>
<button id="googleLogin" class="btn btn-social btn-google-plus" ng-click="doLogin('google')">
<span class="fa fa-google-plus pull-left"></span> <span>Sign in with Google</span>
</button>
Yesterday I was using onclick="hello.login('facebook')", and I suspected that was breaking on certain devices because I shouldn't be using onclick and hello wasn't in scope, so that's why I changed it to ngClick and calling a function in scope. The specific effect of onclick on the users who had errors was to redirect the user to the default/catch-all route without accessing the server at all (I listen for hello events and call the server, so this suggests it wasn't calling hello at all.)
But still, I ask the people who are having issues to re-try (after refreshing obviously), and now they say the button simply does nothing.
Other buttons on the site work. In fact, to get to this page, they use a <button> that uses ui-router to get to this page.
I'm going to continue to search, but I just wanted to ask if I seemed to be hooking hello.js into AngularJS properly, and not making any other beginner mistakes.
I believe the problem is that iPhones and Z10s were blocking hello.js's popup OAuth authentication, but I couldn't just switch it to use page.
When I tried, Facebook returns me to my redirect_url with the fragment
#access_token=....&expires_in=4264&state={%22client_id%22%3A%22164986300332415%22%2C%22network%22%3A%22facebook%22%2C%22display%22%3A%22page%22%2C%22callback%22%3A%22_hellojs_3ojn1yy8%22%2C%22state%22%3A%22%22%2C%22oauth_proxy%22%3A%22https%3A%2F%2Fauth-server.herokuapp.com%2Fproxy%22%2C%22scope%22%3A%22basic%22%2C%22oauth%22%3A{%22version%22%3A2%2C%22auth%22%3A%22https%3A%2F%2Fwww.facebook.com%2Fdialog%2Foauth%2F%22}}
it's ugly, but the point is it starts with a hash tag. So, while hello.js can normally read this, it couldn't in this case because Angular would mangle the address immediately. I'm not sure if this is because I specify to use hash-bangs instead of hash's, but it was.
And I couldn't send this to a PHP script or anything because the fragment after the hashtag would never make it to the PHP script.
So, my solution was to point the redirect_url at an independent page that has hello.js on it, but no Angular. It saves stuff to window.sessionStorage and redirects the user back to the login page, where hello.js passes the user through.
I'm not very confident in this ugly approach yet, so I put a browser sniffer to only do it for iPhones (and use popup for everyone else), I may remove this check in the future (because it's sketchy)
#matt it uses localstorage, not sessionstorage.
Use popup for all, and define a redirect_uri page with just hello.js In it. I dont know why you might think thats sounds wrong. All the demos do it this way. It also gives you a chance to display a nifty loading screen.
Sorry about the ugly fragment. It communcates a lot of state parameters which is used for the oauth proxy... most endpoints like facebook dont need it, so I might refactor that to make it a little less daunting.
I am trying to access Soundcloud from a local HTML page on my laptop. I am stuck at the part of hosting "callback.html" as a redirect_uri. The script I am trying to run is the basic Authenication JavaScript from the Soundcloud documentation page:
<script src="http://connect.soundcloud.com/sdk.js"></script>
<script>
// initialize client with app credentials
SC.initialize({
client_id: 'my_client_id',
redirect_uri: 'http://127.0.0.1/Users/Maria/Documents/SoundcloudClient/callback.html'
});
// initiate auth popup
SC.connect(function() {
SC.get('/me', function(me) {
alert('Hello, ' + me.username);
});
});
</script>
This script gets me to the connect pop-up when I launch the page in Chrome and Firefox.
But, once I have logged in as a Soundcloud user, I get the following error:
Oops! Google Chrome could not connect to 127.0.0.1
If I change my redirect_uri to localhost I get the same error.
If I try:
files:///C:/Users/Maria/Documents/SoundcloudThinClient/callback.html
I get a similar error.
I also tried:
ocalhost:3000
and:
localhost:8080
even though I'm not sure what would be listening on those ports.
So, basically, I'm asking what path do I put for callback.html in order for this to work?
I confess I don't know how the redirct_uri actually functions. I looked at the Oauth pages for it, but I don't understand them. I am beginning to think that I can't simply create an HTML page, paste the JavaScript, create a callback.html file and have this work, even though the SC documentation seems to say that this is possible. If so, what steps am I missing?
I am beginning to attempt this. I believe you have to go to the developer site and sign up as having an app. The redirect uri is asked for and the form gives you an API key you can use in your app.
I'm using drupal so, perhaps adding the oath module and using Php to add the api key might work well.
I had the same problem and I think I solved it.
Morning-after-edit: I posted this dead-tired after working towards a solution through the night. Now, the day after, I realize that you were speaking about the general problem, whereof I face a very particular instance. The following only applies directly to registering soundcloudlabs' soundcloud-group-recorder: https://github.com/soundcloudlabs/soundcloud-group-recorder. There is probably a more general principle lurking behind there, though:
First: yes, you do have to register the app as your own at Soundcloud. At least I presumed so. And doing that, you must register correctly where on your server you will place the callback.html file. Take the ClientID assigned to your app and use that in the API intialize procedure.
Now, I'm a novice and know very little coding. But I started looking around in the main file, application.js.
At the top of the file there are two instances of client_id and redirect_uri each. I'm not sure if that serves a purpose or if one is technically superfluous. Through trial and error I found out that replacing the second instance of each with my own data worked.
Then there is groupId and groupUrl, both of which should contain your info, within quotation marks.
After a lot of trial and error, still having trouble getting the thing to run, I looked around and saw that, whereas early in the file, client_id was hooked within SC.initialize, redirect_uri was not. Under the line:
client_id: CLIENT_ID
I added:
redirect_uri: REDIRECT_URI
– with a customary comma in between. And that's it. It runs.
I need to display on my Web page a simple text string returned from a REST service. I am currently using an XMLHttpRequest:
<div id="returnedText"></div>
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.status == 200 && xhr.readyState == 4) {
document.getElementById("returnedText").innerHTML=xhr.responseText;
}
};
xhr.open("GET",url,true);
xhr.send(null);
</script>
Isn't there a lighter way? I considered using a script tag but the Web service in question doesn't support JSONP. I also did a naive attempt with an iframe (putting the REST url as src) but it didn't work.
I did another attempt with iframes and actually this works fine:
<iframe src="url"></iframe>
Where url is the REST service call.
I must have done something wrong the first time (maybe an authentication issue).
Well the iframe route is clunky since you'd be loading the REST response into it and then reaching into it via JS to get the response. What's more, it would cause a visible load in the browser's address bar area. AJAX came along to do away with the iframe hack :)
JSON-P requires about as much setup as AJAX and if your server doesn't support the callback, that's a none starter.
AJAX needn't be thought heavy. Kick it into its own utility function or, even better, use a library, which makes requests like these do'able in one line. jQuery example:
$.get('some/path').done(function(response) { /* do something */ });