Why setUserID not working in Yandex metrica - yandex

I use yandex metrica in SPA application with VueJs.
at first, I run setUserID after all components load, it didn't work.
so I call it after yandex script init:
(function(m, e, t, r, i, k, a) {
m[i] = m[i] || function() {
(m[i].a = m[i].a || []).push(arguments);
};
m[i].l = 1 * new Date();
k = e.createElement(t), a = e.getElementsByTagName(t)[0], k.async = 1, k.src = r, a.parentNode.insertBefore(k, a);
})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym(11111111, "init", {
clickmap: true,
trackLinks: true,
accurateTrackBounce: true,
webvisor: true
});
const _u = localStorage.getItem('userID');
if (_u)
ym(11111111, "setUserID", _u);
because this method works when the app wasn't SPA.
but now userID is not available in yandex dashboard anymore.
Has any one similar exprience?

Related

Deploying reactjs app to aws amplify results in white screen with error "Uncaught SyntaxError: Unexpected token '<'"

I am trying to deploy a reactjs app to aws amplify and everything works final on localhost and in incognito browser window, just when I access my app url in a regular browser I get this error
If I clear my browser cookies and access the url its fine but everytime I deploy a new build folder it goes back to this. I tried almost every suggestion I could find on the internet but it still occurs.
Solutions I tried :
Setting up PUBLIC_URL in .env file.
Deploying through S3 bucket instead of drag and drop.
Adding <Router basename='/index.html'> to my code.
Adding homepage pointing to my domain in package.json.
Adding homepage pointing to '.' in package.json
Adding homepage pointing to './' in package.json
Adding the above homepage variations to manifest.json in public folder.
Details about my environment and observations :
I am hosting the app on aws amplify with custom domain via Route 53.
App works absolutely fine without any issues on incognito browser - so if there was an issue with the code it should break in incognito as well correct?
The work-around is to clear browser cookies and hit the url again but its undesirable coz this is a production environment and every time I deploy a change I cannot ask my users to clear cookies and try again - changes should be picked up by the browser instantly.
Following is my compiled index.html
<html lang="en">
<head>
<meta charset="utf-8" />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght#400;500;600;700;900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Poppins:wght#400;500;600;700;900&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Vaccination Verification Made Easy" />
<link rel="apple-touch-icon" href="https://vaxtone.com/logo192.png" />
<link href="//netdna.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://js.stripe.com/v3/"></script>
<link rel="manifest" href="https://vaxtone.com/manifest.json" crossorigin="use-credentials">
<title>VaxTone</title>
<link href="https://vaxtone.com/static/css/2.f4136754.chunk.css" rel="stylesheet">
<link href="https://vaxtone.com/static/css/main.dd527d15.chunk.css" rel="stylesheet">
</head>
<body><noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script>"serviceWorker" in navigator && window.addEventListener("load", (function () { navigator.serviceWorker.register("serviceWorker.js").then((function (e) { console.log("ServiceWorker registration successful with scope: ", e.scope) }), (function (e) { console.log("ServiceWorker registration failed: ", e) })) }))</script>
<script>!function (e) { function t(t) { for (var n, a, i = t[0], c = t[1], l = t[2], s = 0, p = []; s < i.length; s++)a = i[s], Object.prototype.hasOwnProperty.call(o, a) && o[a] && p.push(o[a][0]), o[a] = 0; for (n in c) Object.prototype.hasOwnProperty.call(c, n) && (e[n] = c[n]); for (f && f(t); p.length;)p.shift()(); return u.push.apply(u, l || []), r() } function r() { for (var e, t = 0; t < u.length; t++) { for (var r = u[t], n = !0, i = 1; i < r.length; i++) { var c = r[i]; 0 !== o[c] && (n = !1) } n && (u.splice(t--, 1), e = a(a.s = r[0])) } return e } var n = {}, o = { 1: 0 }, u = []; function a(t) { if (n[t]) return n[t].exports; var r = n[t] = { i: t, l: !1, exports: {} }; return e[t].call(r.exports, r, r.exports, a), r.l = !0, r.exports } a.e = function (e) { var t = [], r = o[e]; if (0 !== r) if (r) t.push(r[2]); else { var n = new Promise((function (t, n) { r = o[e] = [t, n] })); t.push(r[2] = n); var u, i = document.createElement("script"); i.charset = "utf-8", i.timeout = 120, a.nc && i.setAttribute("nonce", a.nc), i.src = function (e) { return a.p + "static/js/" + ({}[e] || e) + "." + { 3: "44b4c37d" }[e] + ".chunk.js" }(e); var c = new Error; u = function (t) { i.onerror = i.onload = null, clearTimeout(l); var r = o[e]; if (0 !== r) { if (r) { var n = t && ("load" === t.type ? "missing" : t.type), u = t && t.target && t.target.src; c.message = "Loading chunk " + e + " failed.\n(" + n + ": " + u + ")", c.name = "ChunkLoadError", c.type = n, c.request = u, r[1](c) } o[e] = void 0 } }; var l = setTimeout((function () { u({ type: "timeout", target: i }) }), 12e4); i.onerror = i.onload = u, document.head.appendChild(i) } return Promise.all(t) }, a.m = e, a.c = n, a.d = function (e, t, r) { a.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: r }) }, a.r = function (e) { "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(e, "__esModule", { value: !0 }) }, a.t = function (e, t) { if (1 & t && (e = a(e)), 8 & t) return e; if (4 & t && "object" == typeof e && e && e.__esModule) return e; var r = Object.create(null); if (a.r(r), Object.defineProperty(r, "default", { enumerable: !0, value: e }), 2 & t && "string" != typeof e) for (var n in e) a.d(r, n, function (t) { return e[t] }.bind(null, n)); return r }, a.n = function (e) { var t = e && e.__esModule ? function () { return e.default } : function () { return e }; return a.d(t, "a", t), t }, a.o = function (e, t) { return Object.prototype.hasOwnProperty.call(e, t) }, a.p = "https://vaxtone.com/", a.oe = function (e) { throw console.error(e), e }; var i = this["webpackJsonpvaxtone1.0"] = this["webpackJsonpvaxtone1.0"] || [], c = i.push.bind(i); i.push = t, i = i.slice(); for (var l = 0; l < i.length; l++)t(i[l]); var f = c; r() }([])</script>
<script src="https://vaxtone.com/static/js/2.3e8f6948.chunk.js"></script>
<script src="https://vaxtone.com/static/js/main.6ccb123a.chunk.js"></script>
</body>
<style>
body::-webkit-scrollbar {
display: none
}
body {
-ms-overflow-style: none;
scrollbar-width: none
}
</style>
</html>
I used the create-react-app command to create the reactjs app and use npm run build to generate the build folder for deployment.
I use a service worker to implement progressive-web-app features - could it be something related to my service worker?
Any help on how to resolve this or what do you think is happening would be a big big help .Thanks.
Make sure your package json file either does not have homepage set or the value for homepage matches your AWS Amplify URL. I had the same issue and this resolved it.

Pass gtm id dynamically to gtm script in head section

I have integrated google tag manager in my react js application but the problem is I have to pass the gtm id present in gtm script dynamically and turn on and off datalyer dynamically depending upon the response of the value coming from API.
I have created a component LoadAppKeys which receives a value on which I decide whether gtm is enabled or not. But how do I pass the gtm id dynamically to the script present in head section of index.html and append the script in head if value is 1 and not if its 0.
class LoadAppKeys extends React.PureComponent {
componentDidMount() {
this.props.getStorefrontConfigs();
}
componentWillReceiveProps(nextProps) {
if (!nextProps.loading) {
const gtm = getGTM(nextProps.storefrontConfig);
if (R.equals(gtm.gtm_enabled, 1)) {
var script = document.createElement('script');
script.type = "text/javascript";
script.text = myGTM(window, document, 'script', 'dataLayer', "GTM-KQZGSBW");
document.head.appendChild(script);
}
}
}
-------------------------------------
function myGTM(w, d, s, l, i) {
(function (w, d, s, l, i) {
w[l] = w[l] || []; w[l].push({
'gtm.start':
new Date().getTime(), event: 'gtm.js'
}); var f = d.getElementsByTagName(s)[0],
j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src =
'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'dataLayer', gtm_id);
}
Want to load the script everytime the page based upon the value in loadAppKeys component.
You can directly call myGTM, instead of doing the whole script insertion. Otherwise if you want to do the insertion all you need is determine the src attribute, example:
script src = 'https://www.googletagmanager.com/gtm.js?id='+id
In there you don't mention how you get the id, but basically change id with your variable.

Nedb non-unique _id indexing

I have a Nedb database for my electron.js app that generates _id replicas even with ensureIndex({… unique: true}). Onclick, an indexed value is to increment by 5 - instead a new index is generated with said value. Example:
// Before click
{"_id":0,"testVal":0}
{"_id":1,"testVal":0}
{"_id":2,"testVal":0}
…
// After click
{"_id":0,"testVal":0} // Intended: {"_id":0, "testVal":5}
{"_id":1,"testVal":0}
{"_id":2,"testVal":0}
…
{"_id":0,"testVal":5}
Relevant code:
var Datastore = require('nedb');
db = new Datastore ({filename: 'db/rtest.db', autoload: true});
// Database functions
exports.createTestVal = function(i, passVal) {
var test = {_id: i, testVal: passVal};
db.insert(test, function(err, newDoc){})};
exports.updateTestVal = function(i, passVal) {
db.update({_id: i}, {$set: {"testVal": passVal}}, {}, function(err, numReplaced){});}
exports.getTestVal = function(fnc){
db.find({}, function(err, docs) {fnc(docs)})}
exports.deleteTestVal = function(id) {
db.remove({_id: id}, {}, function(err, numRemoved){})}
// Event functions
const database = require('../assets/js/testdatabase'); // 'testdatabase' = code above
var btnTst = document.getElementById('add5'); var i = 0;
db.ensureIndex({ fieldName: "_id", unique: true }, function (err) {});
btnTst.addEventListener('click', function(event){
var value = Number(this.value);
database.updateTestVal(i, value);
i++;})
window.addEventListener('load', function() {
database.getTestVal(function(testVals) {
for (k = 0; k < 10; k++) {if (testVals.length == k){fillValues(k)}}})})
function fillValues(k){for (p = k; p < 10; p++){database.createTestVal(p, 0)}}
<button id="add5" value=5>+5</button>
Tried modifying variable types, reordering functions, among others - to no avail. The GitHub documentation claims that _id is uniquely-indexed by default, but isn't so in my use.
Any workarounds?
Assuming that you are seeing these "duplicates" while viewing the physical file that your database is being written to, everything is working as expected.
From the NeDB documentation:
Persistence
Under the hood, NeDB's persistence uses an append-only format, meaning that all updates and deletes actually result in lines added at the end of the datafile, for performance reasons. The database is automatically compacted (i.e. put back in the one-line-per-document format) every time you load each database within your application.

AngularJS: Right approach for using Google Analytics

I am wondering which is the right way of integrating Google Analytic into my AngularJS app. I would like to provide it through DI, so I can mock it during unit testing, and test which data is being sent to it.
I was trying something like this:
.service('$ga', function () {
(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', 'GA_KEY', 'auto');
ga('send', 'pageview');
return ga;
})
But of course it does not work, since first is a dummy object and when analytics.js loads, replaces window.qa (ie:window[document['GoogleAnalyticsObject']]) with the proper implementation. So when the service runs, returns the dummy implementation.
I guess that using a provider will be the right way, since I would like to also configure some parameters (like UserID, etc...), but I have no idea how to set it up that way.
Which is the right approach?
This is the best I got so far:
.provider('$ga', function () {
window['GoogleAnalyticsObject'] = 'ga';
window['ga'] = window['ga'] || function () { (window['ga'].q = window['ga'].q || []).push(arguments)}
window['ga'].l = 1 * new Date();
var script = document.createElement('script');
var prevScript = document.getElementsByTagName('script')[0];
script.async = 1;
script.src = '//www.google-analytics.com/analytics.js';
prevScript.parentNode.insertBefore(script, prevScript);
var provider = function () {
var me = {};
me.$get = function () {
ga('send', 'pageview');
return function () {
return window.ga.apply(window, arguments);
}
};
me.ga = function () {
return window.ga.apply(window, arguments);
};
return me;
};
return provider();
})
It is a provider that can be configured:
.config(['$gaProvider',function ($gaProvider) {
$gaProvider.ga('create','UA-XXXXXX-Y','auto');
}])
Feedback is welcomed.

Angularjs ui for bootstrap

i'm using the Angularjs ui for bootstrap library. In particular im, wanting to customise the the behaviour of the "collapse" directive. Currently, if i have more than one collapsable section on a page itcollapses them all at the same time. I would like to seperate them out so i can know which element triggered the event. And collapse only that section. Ive tried a few different ways including adding the $event expression inside ng-click but its coming back undefined.
I was hoping that someone could help me fix this code please?
.directive("collapse", ["$transition", function (e, $event) { var t = function (e, t, n) { t.removeClass("collapse"), t.css({height: n}), t[0]. offsetWidth, t.addClass("collapse") };
return{link: function (n, a, i) { var r, o = !0; n.$watch(function () { return a[0].scrollHeight }, function () { 0 !== a[0].scrollHeight && (r || (o ? t(n, a, a[0].scrollHeight + "px") : t(n, a, "auto"))) }), n.$watch(i.collapse, function (e) { console.log(r); e ? u() : c() //removed for testing }); var l, s = function (t) { return l && l.cancel(), l = e(a, t), l.then(function () { l = void 0 }, function () { l = void 0 }), l }, c = function () {
o ? (o = !1, r || t(n, a, "auto")) : s({height: a[0].scrollHeight + "px"}).then(function () { r || t(n, a, "auto") }), r = !1 }, u = function () { r = !0, o ? (o = !1, t(n, a, 0)) : (t(n, a, a[0].scrollHeight + "px"), s({height: "0"})) } }} }])
Your problem is likely that you have used the same scope variable for collapse for each of the inidividual instances. This would wire them all together.
As you can see from this demo, they play well together when the variables are different
DEMO

Resources