How can I call addTelemetryInitializer when using the latest Javascript snippet? - azure

I am trying to customise the name attribute for pageview events
This has previously been asked, for example How to provide custom names for page view events in Azure App Insights?
but this and all other solutions I've found (and the Microsoft documentation too) are working with an old version of the javascript snippet, of the form
window.appInsights = appInsights;
// …
appInsights.trackPageView();
The current snippet from the portal is very different though
var sdkInstance="appInsightsSDK";window[sdkInstance]="appInsights";var // ...
{
instrumentationKey:"key"
}); window[aiName] = aisdk,aisdk.queue && aisdk.queue.length ===0 && aisdk.trackPageView({});
I've tried this sort of thing
var sdkInstance="appInsightsSDK";window[sdkInstance]="appInsights";var aiName=window[sdkInstance],aisdk=window[aiName]||function(e){function n(e){t[e]=function(){var n=arguments;t.queue.push(function(){t[e].apply(t,n)})}}var t={config:e};t.initialize=!0;var i=document,a=window;setTimeout(function(){var n=i.createElement("script");n.src=e.url||"https://az416426.vo.msecnd.net/scripts/b/ai.2.min.js",i.getElementsByTagName("script")[0].parentNode.appendChild(n)});try{t.cookie=i.cookie}catch(e){}t.queue=[],t.version=2;for(var r=["Event","PageView","Exception","Trace","DependencyData","Metric","PageViewPerformance"];r.length;)n("track"+r.pop());n("startTrackPage"),n("stopTrackPage");var s="Track"+r[0];if(n("start"+s),n("stop"+s),n("setAuthenticatedUserContext"),n("clearAuthenticatedUserContext"),n("flush"),!(!0===e.disableExceptionTracking||e.extensionConfig&&e.extensionConfig.ApplicationInsightsAnalytics&&!0===e.extensionConfig.ApplicationInsightsAnalytics.disableExceptionTracking)){n("_"+(r="onerror"));var o=a[r];a[r]=function(e,n,i,a,s){var c=o&&o(e,n,i,a,s);return!0!==c&&t["_"+r]({message:e,url:n,lineNumber:i,columnNumber:a,error:s}),c},e.autoExceptionInstrumented=!0}return t}(
{
instrumentationKey:"my-key"
}); window[aiName] = aisdk;
if (aisdk.queue && 0 !== aisdk.queue.length) {
function adjustPageName(item) {
var name = item.name.replace("AppName", "");
if (name.indexOf("Order") !== -1)
return "Order";
if (name.indexOf("Product") !== -1)
return "Shop";
// And so on...
return name;
}
// Add telemetry initializer
aisdk.queue.push(function () {
aisdk.context.addTelemetryInitializer(function (envelope) {
var telemetryItem = envelope.data.baseData;
// To check the telemetry item’s type:
if (envelope.name === Microsoft.ApplicationInsights.Telemetry.PageView.envelopeType || envelope.name === Microsoft.ApplicationInsights.Telemetry.PageViewPerformance.envelopeType) {
// Do not track admin pages
if (telemetryItem.name.indexOf("Admin") !== -1)
return false;
telemetryItem.name = adjustPageName(telemetryItem);
}
});
});
aisdk.trackPageView();
};
But it doesn't work (no errors, but no effect on the telemetry either)
Has anyone managed to get anything like this working using the new snippet?

Please try the code below, I can add a custom property by using the latest javascript code snippet:
var sdkInstance="appInsightsSDK";window[sdkInstance]="appInsights";var aiName=window[sdkInstance],aisdk=window[aiName]||function(e){function n(e) { t[e] = function () { var n = arguments; t.queue.push(function () { t[e].apply(t, n) }) } }var t={config: e};t.initialize=!0;var i=document,a=window;setTimeout(function(){var n=i.createElement("script");n.src=e.url||"https://az416426.vo.msecnd.net/scripts/b/ai.2.min.js",i.getElementsByTagName("script")[0].parentNode.appendChild(n)});try{t.cookie = i.cookie}catch(e){}t.queue=[],t.version=2;for(var r=["Event","PageView","Exception","Trace","DependencyData","Metric","PageViewPerformance"];r.length;)n("track"+r.pop());n("startTrackPage"),n("stopTrackPage");var s="Track"+r[0];if(n("start"+s),n("stop"+s),n("setAuthenticatedUserContext"),n("clearAuthenticatedUserContext"),n("flush"),!(!0===e.disableExceptionTracking||e.extensionConfig&&e.extensionConfig.ApplicationInsightsAnalytics&&!0===e.extensionConfig.ApplicationInsightsAnalytics.disableExceptionTracking)){n("_" + (r = "onerror")); var o=a[r];a[r]=function(e,n,i,a,s){var c=o&&o(e,n,i,a,s);return!0!==c&&t["_"+r]({message: e,url:n,lineNumber:i,columnNumber:a,error:s}),c},e.autoExceptionInstrumented=!0}return t}(
{
instrumentationKey: "xxxxxxxxxx"
}
); window[aiName] = aisdk, aisdk.queue && 0 === aisdk.queue.length;
// Add telemetry initializer
aisdk.queue.push(function () {
var telemetryInitializer = (envelope) => {
//Add a custom property
envelope.data.name = 'This item passed through my telemetry initializer';
};
appInsights.addTelemetryInitializer(telemetryInitializer);
});
aisdk.trackPageView({})
Then in azure portal, the custom property is added:

Related

Forge viewer isLayerVisible is always false

For some reason I get always false on viewer.isLayerVisible(layerNode).
I followed this tutorial https://forge.autodesk.com/blog/toggle-sheet-layer-visibility
I have event handler on LAYER_VISIBILITY_CHANGED_EVENT, here is my code snippet in typescript:
viewer.addEventListener(Autodesk.Viewing.LAYER_VISIBILITY_CHANGED_EVENT, (e) => {
var root = viewer.model["myData"].layersRoot; //getLayersRoot() is not a function for some reason
var overlayLayer = viewer["getSelectedLayer"]();
if (viewer["layerRoot"] != undefined) {
var layerNode = root.children.filter((e) => { return e.name === overlayLayer })
var isLayerVisible = viewer.isLayerVisible(layerNode);
//show layer
if (isLayerVisible) {
viewer.impl.addOverlay("Edit2D", viewer["savedPoints"].overlayLayer)
}
//hide layer
else {
viewer.impl.removeOverlayScene("Edit2D")
}
}
});
After switching some layers from layer manager off, I also get viewer.areAllVisible() as true.
Forge viewer version is 7.*
Do you have any advice? Thanks!
I found out that you can access visible and visible layers from indexToLayer viewer property
var visibleLayers = Array.from(viewer.impl.layers.indexToLayer.filter(e => e != null && e.visible));

Update only if key exist firebase cloud functions

I have a function that counts all the members that are going to do a event.
I have the registered_people key to count how many users are on this event. This key is updated +1 or -1 when someone adds itself to the /registrations/approved link.
This works very well. See the method below.
exports.reservation = functions.database.ref('/agenda/activitys/{year}/{month}/{day}/{time}/{event}/registrations/approved/{key}').onWrite((event) => {
var collectionRef = event.data.adminRef.parent.parent;
var countRef = collectionRef.parent.child('registered_people');
console.log("Fired of reservation watcher");
return countRef.transaction(function(current) {
if (event.data.exists() && !event.data.previous.exists()) {
return (current || 0) + 1;
}
else if (!event.data.exists() && event.data.previous.exists()) {
return (current || 0) - 1;
}
});
});
But my problem is when the admin deletes an event. Url /agenda/activitys/{year}/{month}/{day}/{time}/{event} gets deleted, and the method defined above gets triggered and writes data again to the url. How can I prevent that this method writes anything when an admin deletes the event?
And this code is not working:
if (event.data.previous.exists()) {
return;
}
Because when a user wants to sign out from an event the registered_people must be updated. With the code defined above the delete does not work anymore. So I need to check if the event is deleted.
First, you are running and old version of functions & admin, update to be sure your firebase-functions & firebase-admin are updated:
In your functions folder run:
npm install firebase-functions#latest --save
npm install firebase-admin#latest --save
Then your code should look like this:
exports.reservation = functions.database.ref('/agenda/activitys/{year}/{month}/{day}/{time}/{event}/registrations/approved/{key}').onWrite((change, context) => {
var collectionRef = change.after.ref.parent.parent;
var countRef = collectionRef.parent.child('registered_people');
let increment;
if (change.after.exists() && !change.before.exists()) {
increment = 1;
} else if (!change.after.exists() && change.before.exists()) {
return null;
} else {
return null;
}
return countRef.transaction((current) => {
return (current || 0) + increment;
}).then(() => {
return console.log('Counter updated.');
});
});

SP.Ribbon.WebPartComponent.getWebPartAdder() returns undefined

I am using the source at http://blog.symprogress.com/2010/11/ribbon-insert-any-web-part-using-javascript/ to handle user web part button click event.
The function 'addWebPart()' calls a function 'SP.Ribbon.WebPartComponent.getWebPartAdder()' which is supposed to return adder instance but sometimes it returns undefined.
If I add a while loop to wait for the instance value to return correctly, the browser in my VM stalls for some time. When an instance is returned, the browser becomes responsive again. This only happens in some instances.
I am using SharePoint 2013 and the section of code I am referring to is:
addWebPart = function (wpCategory, wpTitle) {
var webPartAdder = SP.Ribbon.WebPartComponent.getWebPartAdder();
while (webPartAdder == undefined)
webPartAdder = SP.Ribbon.WebPartComponent.getWebPartAdder();
// ... Other stuff ...
}
How can this issue be resolved?
For anyone looking for an answer to this question, turns out you have to call 'LoadWPAdderOnDemand()' function then wait for the event '_spEventWebPartAdderReady'. Then query for 'window.WPAdder':
addWebPartDelayed = function (webPartAdder, wpCategory, wpTitle) {
var webPart = findWebPart(webPartAdder, wpCategory, wpTitle);
if (webPart) {
var zone = WPAdder._zones[0];
var wpid = WPAdder._createWebpartPlaceholderInRte();
WPAdder.addItemToPageByItemIdAndZoneId(webPart.id, zone.id, 0, wpid);
}
else
alert('ERROR: Web part not found! Please try again after sometime.');
},
addWebPart = function (wpCategory, wpTitle) {
var webPartAdder = window.WPAdder;
if (webPartAdder == undefined) {
LoadWPAdderOnDemand();
ExecuteOrDelayUntilEventNotified(
function () {
var webPartAdder = window.WPAdder;
addWebPartDelayed(webPartAdder, wpCategory, wpTitle);
},
"_spEventWebPartAdderReady");
}
else
addWebPartDelayed(webPartAdder, wpCategory, wpTitle);
};

nodejs events prototyping and its scope using that = this

I am trying to develop in Nodejs using its evented system. I've implemented the following code and it passes my tests (using mocha). However, I am not confident that it will work in a production environment because of the the scope of the that variable.
In my code, I assign that=this. Afterwards I assign the config object to that.config and the callback emits the event without passing config as a parameter. Then the listener function uses the that.config to emit another signal. The cache object is a request to a redis database.
The question is: will the that.config object always refer to the scope when I've emitted the signal or could it be modified by another request (that gets another config) after the first emitted signal but before the first listener uses that.config (inside another callback)?
function SensorTrigger(sensorClass, configClass) {
this.sensorClass = sensorClass || {'entityName': 'sensor'};
this.configClass = configClass || {'entityName': 'config'};
this.cache = new CacheRedis(app.redisClient, app.logmessage);
events.EventEmitter.call(this);
}
util.inherits(SensorTrigger, events.EventEmitter);
SensorTrigger.prototype.getSensorConfig = function(sensor, trigger) {
var that = this
, sensorKeyId = that.sensorClass.entityName + ':' + sensor
, baseKeyId = "base";
that.trigger = trigger;
that.id = sensor;
var callBack = function (config) {
config = utils.deepen(config);
that.receiver = config.receiver;
that.config = config.triggers[that.trigger];
that.emit(that.config.data, sensor);
}
that.cache.getItem(that.configClass, sensorKeyId, function(err, config) {
if (!config) {
that.cache.getItem(that.configClass, baseKeyId, function(err, config) {
callBack(config);
})
} else {
callBack(config);
}
})
}
SensorTrigger.prototype.getAllData = function(sensor) {
var that = this;
that.cache.getAllData(that.sensorClass, sensor, function(err, data) {
if (err) {
that.emit("error", err);
} else {
that.emit(that.config.aggregation, sensor, data);
}
})
}
trigger = new SensorTrigger();
trigger.on("onNewData", trigger.getSensorConfig);
trigger.on("all", trigger.getAllData);
An example of the config object:
{
"id": "base",
"triggers.onNewData.data": "all",
"triggers.onNewData.aggregation": "max",
"triggers.onNewData.trigger": "threshold",
"receiver.host": "localhost",
"receiver.port": "8889",
"receiver.path": "/receiver"
}
Only if the next time it runs "that" is changed to a different instance of this. Since each instance has it's own function, the only way that could happen is if you do something like:
var trigger = new SensorTrigger(sensor, config);
trigger.getSensorConfig.apply(SOMETHING_ELSE, sensor2, trigger2);
As long as you use it like you normally would:
var trigger = new SensorTrigger(sensor, config);
trigger.getSensorConfig(sensor2, trigger2);
//or even:
trigger.getSensorConfig.apply(trigger, sensor2, trigger2);
It is fine. What you are doing is a common practice in JavaScript, and used in production all the time.

CKEditor: Using dialogDefinition.onShow() throws C.preview not defined

Modifying CKEditor 3.6.2 is not easy, but I tried hard. One problem that is still open is the following:
In config.js we have:
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if(dialogName == 'image') {
dialogDefinition.onShow = function () {
var dialog = CKEDITOR.dialog.getCurrent();
var elem = dialog.getContentElement('info','htmlPreview');
elem.getElement().hide();
// and more stuff to do...
};
}
});
After the editor is loaded, and the user has uploaded an image, the following javascript error is thrown:
Error: C.preview is undefined
Source File: wysiwyg-editor/plugins/image/dialogs/image.js?t=B8DJ5M3
Line: 8
dialogDefinition.onShow seems to cause this error, as removing all elements from the code, and only calling onShow brings up the error. Using onLoad does work!
Using onShow on other dialogs is working fine, only the image dialog is not working as it should.
Btw, I asked in the CKEditor forum but nobody answered.
Stumbled across this when I was looking for a resolution. Figured I'd post what I ultimately did to solve it, albeit not 100% ideal.
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var tab, field, name = ev.data.name,
definition = ev.data.definition;
if( name == 'image' )
{
tab = definition.getContents( 'info' );
field = tab.get( 'htmlPreview' );
field.style = 'display: none';
}
});
This makes the preview window available for processing, just hides it from the dialog window.
Use CKEDITOR.tools.setTimeout() like this:
CKEDITOR.on('dialogDefinition', function(ev) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
var dialog = dialogDefinition.dialog;
if (dialogName == 'image2') {
dialogDefinition.onShow = CKEDITOR.tools.override(dialogDefinition.onShow, function(original) {
return function() {
original.call(this);
CKEDITOR.tools.setTimeout( function() {
if (dialog.getContentElement('info', 'src').getValue() == '') {
dialog.selectPage('Upload');
}
}, 0);
}
});
}
});

Resources