I need to fire adobe data layer when the pagination changes - javascript

i need to fire/analytics code a pageLoad event whenever a user navigate to different page in the pagination. i
// pageLoad.js
export const PageLoad = () => {
const URL = lowerCaseElement(window.location.href);
const pageLoadObject = {
event: "pageLoad",
page: {
URL,
},
user: {
email: loginInfo?.email || null,
loginStatus: loginInfo ? 'loggedin' : 'anonymous',
}
}
console.log(pageLoadObject);
{
"event": "pageLoad",
"page": {
"URL": "http://localhost:4502/content/my-account/my-list.html?page=2",
},
"user": {
"loginType": "loggedin",
"email": "kiranxxxxxx#gmail.com",
}
}
window.adobeDataLayer.push(pageLoadObject);
}
// pagination.js
import { paginationPageLoad } from '../PageLoad'
const Pagination = (props) => {
useEffect(() => {
paginationPageLoad();
}, [currentPage]);
}
the currentPage is state which consists of page number, i need to fire the adobe.datalayer.push everytime the user navigates between pages. apparently is not working as excepted the event is not firing.
console.log("pageLoad", window.adobeDataLayer.find(
(activity) => activity.event === 'pageLoad'
));
{
"event": "pageLoad",
"page": {
"URL": "http://localhost:4502/content/my-account/my-list.html?page=1",
},
"user": {
"loginType": "loggedin",
"email": "kiranxxxxxxx4#gmail.com",
}
}
when i watch the event the pageLoad event is same when the component renders. like for every navigation the url must be changing but it is same.

Related

How to dispatch event on Push receive using Workbox?

I have a VueJS component where I listen for pushMessageEvent :
<template>
<div>
<VueBotUI
:options="options"
:is-open="isOpen"
:bot-typing="botTyping"
:input-disable="inputDisable"
:messages="messages"
#msg-send="onSend"
></VueBotUI>
</div>
</template>
<script>
export default {
components: {
VueBotUI
},
data: function () {
return {
options: {botTitle: 'test',},
user: {msg: null,},
msgRegex: /^[a-zA-Z ]+$/,
messages: []
}
},
mounted() {
document.addEventListener('pushMsgEvent', this.printPush);
},
beforeDestroy () {
document.removeEventListener('pushMsgEvent', this.printPush);
},
methods: {
printPush (e) {
console.log(e)
console.log("------------------")
console.log(e.detail)
},
}
}
</script>
And I want to fire this pushMessageEvent when I get a Push event in my service-worker:
/* eslint-disable */
importScripts(
"https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"
);
// Load all ENVERYWHERE enviroment variables
importScripts('./env-vars.js')
const PushMsgEvent = new CustomEvent('pushMsgEvent', { detail: null });
workbox.core.skipWaiting();
workbox.core.clientsClaim();
self.__WB_MANIFEST;
// Listen to push event
self.addEventListener("push", (event) => {
if (event.data) {
console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
PushMsgEvent.detail = event.data.text();
//document.dispatchEvent(PushMsgEvent);
}
});
workbox.precaching.precacheAndRoute([]);
but I can't use document.dispatchEvent since I get document is not defined, is it a workaround to fire this event and catch it in my component ?
I have read about workbox-window but I can't figure out how to fire my event from the service-worker in order to catch it in the component
My solution:
service-worker.js:
// Listen to push event
self.addEventListener("push", (event) => {
if (event.data) {
self.clients.matchAll().then(clients => {
clients.forEach(client => {
client.postMessage(JSON.stringify(event.data.text()));
});
});
}
});
my component.vue :
mounted() {
navigator.serviceWorker.addEventListener('message', event => {
let msg = event.data;
this.printPush(msg);
});
},
beforeDestroy () {
navigator.serviceWorker.removeEventListener('message', event => {
this.printPush(event);
});
},
methods: {
printPush (e) {
console.log(e)
}
}

SAPUI5 JSON REST API (non-oData) mock server

How is it possible to use a mock server for JSON REST API and not for a oData service?
I would like to mock http://localhost:8080/api/v1/configs to get a JSON list of all configurations even if I have no backend connection and I am running the app in mock mode.
The following is not working, it returns furthermore the real data and not the mocked data.
mockserver.js:
sap.ui.define([
"sap/ui/core/util/MockServer",
"sap/base/util/UriParameters"
], function (MockServer, UriParameters) {
"use strict";
var oTokenRequest = {
method: "GET",
path: new RegExp("/actuator/info"),
response: function (oXhr, sNodeId) {
jQuery.sap.log.debug("Incoming request for X-CSRF Token");
oXhr.respondJSON(200, {
"X-Csrf-Token": "myFakeToken"
}, {});
}
};
var oMockServer;
return {
init: function () {
var oUriParameters = new UriParameters(window.location.href);
// configure mock server with a delay
MockServer.config({
autoRespond: true,
autoRespondAfter: oUriParameters.get("serverDelay") || 500
});
var oAllConfigurations = {
method: "GET",
path: "/configs", // or "new RegExp(".*?")" for everything after v1/?
response: function (oXhr, sUrlParams) {
oXhr.respondJSON(200, {}, JSON.stringify({
"uuid": "50df30x9-762b-341c-9881-7315l242b6c5",
"name": "Config1",
"description": "Mapping for component1",
"fileVersion": 3,
"createdAt": 1581517043000,
"updatedAt": 1589039157000
}, {
"uuid": "4f68da04-28a2-4a4e-947k-6d7be70cr03k",
"name": "MOCKSERVER-Config2",
"description": "Mapping for component2",
"fileVersion": 12,
"createdAt": 1553685823000,
"updatedAt": 1589363607000
}, {
"uuid": "6g6chg1-23a2-4a3o-332a-2a6be08ca02f",
"name": "Config3",
"description": "Mapping for component3",
"fileVersion": 1,
"createdAt": 1596119686000,
"updatedAt": 1596119686000
}));
}
};
var aRequests = [oTokenRequest];
aRequests = aRequests.concat(oAllConfigurations);
// create
this.oMockServer = new MockServer({
rootUri: "http://localhost:8080/api/v1",
requests: [oAllConfigurations]
});
// start
this.oMockServer.start();
}
};
});
data-sap-ui-oninit in mockServer.html leads to initMockServer.js
initMockServer.js:
sap.ui.define([
"../localService/mockserver"
], function (mockserver) {
"use strict";
// initialize the mock server
mockserver.init();
// initialize the embedded component on the HTML page
sap.ui.require(["sap/ui/core/ComponentSupport"]);
});
Main.controller.js:
//...
_getConfigList: function () {
var oModelConfigList = new JSONModel();
this.request = new BaseRequests();
return fetch("http://localhost:8080/api/v1/configs")
.then((response) => {
if (response.ok) {
return response.json();
} else {
MessageToast.show(response.statusText);
return null;
}
}).then(json => {
if (json) {
oModelConfigList.setData(json);
this.getView().setModel(oModelConfigList, "ConfigList");
}
});
},
//...
The UI5-Mockserver is only for the UI5 V2-Model implementation. Hence you need to build your own.
To keep it as simple as possible; i would suggest to pack everything in a delegate and use a global flag to toggle mock/real requests during runtime.
//
// your delegate
//
sap.ui.define([
"sap/ui/base/Object"
], function (BaseObject) {
"use strict";
const mockData = {
"uuid": "50df30x9-762b-341c-9881-7315l242b6c5",
"name": "Config1",
"description": "Mapping for component1",
"fileVersion": 3,
"createdAt": 1581517043000,
"updatedAt": 1589039157000
}, {
"uuid": "4f68da04-28a2-4a4e-947k-6d7be70cr03k",
"name": "MOCKSERVER-Config2",
"description": "Mapping for component2",
"fileVersion": 12,
"createdAt": 1553685823000,
"updatedAt": 1589363607000
}, {
"uuid": "6g6chg1-23a2-4a3o-332a-2a6be08ca02f",
"name": "Config3",
"description": "Mapping for component3",
"fileVersion": 1,
"createdAt": 1596119686000,
"updatedAt": 1596119686000
}
return BaseObject.extend("my.namespace.delegate.config", {
read: function(){
if(!window.MY_NAME_SPACE_MOCK){
return fetch("api/v1/configs")
.then((response) => {
if (response.ok) {
return response.json();
} else {
//MessageToast.show(response.statusText);
return null;
}
})
}else{
return new Promise((resolve, reject) => {
let wait = setTimeout(() => {
clearTimout(wait);
resolve(mockData);
}, 2000)
})
}
},
});
});
// usage
sap.ui.define([
"my/namespace/delegate/config"
], function (Config) {
onInit: function() {
this._config = new Config();
this._config.read()
.then((data)=>{
console.log("data can be mock or real depending on MY_NAME_SPACE_MOCK")})
},
})
//
// switch on/off mocking anywhere
//
window.MY_NAME_SPACE_MOCK = true;
delete window.MY_NAME_SPACE_MOCK
FYI: domain("localhost") is not part of a normal AJAX request. Once it is deployed; this will not work anymore

Chrome extension - button listener on notification executes multiple times

I am writing a chrome extension that makes requests to an API and I have noticed that after I create a notification from background script using chrome's notification API, the listeners on the buttons from the notification are executed multiple times. on the first run only once and then increasing. I figured that the listeners just add up on the page but I couldn't find a way to sort of refresh the background page.
This is the function that creates the notification and it's listeners.
var myNotificationID
const displayNotification=(userEmail, password, website,username) =>{
chrome.notifications.create("", {
type: "basic",
iconUrl: "./icon128.png",
title: "PERMISSION",
requireInteraction: true,
message: "question",
buttons: [{
title: "YES",
}, {
title: "NO",
}]
}, function(id) {
myNotificationID = id;
})
chrome.notifications.onButtonClicked.addListener(function(notifId, btnIdx) {
if (notifId === myNotificationID) {
if (btnIdx === 0) {
console.log('inserting')
try{
fetch (`http://localhost:8080/users/${userEmail}/accounts`,{
})
}catch(err){
}
} else if (btnIdx === 1) {
console.log('clearing')
chrome.notifications.clear(myNotificationID)
}
}
});
}
And this is where the function is called
chrome.runtime.onMessage.addListener((message, sender, response)=>{
if(message.message === 'showNotification'){
console.log('received insert')
displayNotification(message.userEmail,message.password, message.currentSite,message.username)
response({status:"received"})
}
})
the fetch within the listener is executed multiple times but the log from the onMessage listener is only displayed once, so the listener is the problem here.
I tried chrome.notifications.onButtonClicked.removeListener(), but as i mentioned there was no success.
Are there any other ways in which i could clean the listeners from the background script once they are used?
Using a notification store:
const notificationsByID = {};
chrome.notifications.onButtonClicked.addListener((notifId, btnIdx) => {
// Avoid access to the notification if not registered by displayNotification
if (!notificationsByID[ notifId ]) { return null; }
if (btnIdx === 0) {
console.log('inserting')
try{
fetch (`http://localhost:8080/users/${ notificationsByID[ notifId ].userEmail }/accounts`,{ /**/ });
}catch(err){
console.log(err);
}
delete notificationsByID[ notifId ]; // Cleanup
} else if (btnIdx === 1) {
console.log('clearing')
chrome.notifications.clear(myNotificationID);
delete notificationsByID[ notifId ]; // Cleanup
}
});
chrome.notifications.onClosed.addListener((notifId) => {
if (notificationsByID[ notifId ]) { delete notificationsByID[ notifId ]; }
});
const displayNotification=(userEmail, password, website,username) =>{
chrome.notifications.create("", {
type: "basic",
iconUrl: "./icon128.png",
title: "PERMISSION",
requireInteraction: true,
message: "question",
buttons: [{ title: "YES", }, { title: "NO", }]
}, function(id) {
// Insertion
notificationsByID[ id ] = { userEmail, password, website,username };
})
}

How to fetch json data using vuejs component?

I want to access json data from external file using vue component but I am not able to get any output in web page.The below is my code which I have tried.Can anyone help me out?
The below is Json data that included the models which I want to display on web page
{
"models": [
{
"title": "IRIS",
"project": "ABC",
"category": "SINGLES",
"bedrooms": 3
},
{
"title": "LILAC",
"project": "ABC",
"category": "DOUBLE",
"bedrooms": 4
},
{
"title": "ASTER",
"project": "ABC",
"category": "SINGLES",
"bedrooms": 4
}
]
}
Vue.component('single-model', {
data: function() {
return {
myData: []
}
},
template: `<div v-for="model in myData">
<p>{{model.title}}</p>
<hr>
</div>`,
created: function() {
this.fetchData();
},
methods: {
fetchData: function() {
var url = 'j.json';
axios.get(url)
.then(function(res) {
this.myData = res.data.models;
});
}
}
});
var vm = new Vue({
el: '#app',
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<div id="app">
<single-model></single-model>
</div>
As you might have noticed white running the provided snippet, template can have only one child element, using a v-for on the outermost element will create multiple children.
this in your case is not referring to the vue-component in fetchData function.
methods:{
fetchData() {
var url = '';
axios.get(url)
.then((res) => {
this.myData = res.data;
});
}
},
Try replacing with the above snippet in your code.
this on your code is not referring to your Vue Component.
I think, the easiest way to solve this issue is by creating a new variable to refer to your Vue Component
fetchData: function() {
var url = 'j.json';
var self = this;
axios.get(url)
.then(function(res) {
self.myData = res.data.models;
});
}

Mitrhil.js conditional routing and authentication

I'm studying javascript and mithril.js 1.1.6. I'm writing down a simple web app in which users land on a page where he can login. Users who already did login land on a different page. I'm trying this using conditional routing, here is the main component:
const m = require("mithril");
...
import Eventbus from './whafodi/eventbus.js';
import WelcomePage from './ui/welcome.js';
import User from './model/user.js';
var eventbus = new Eventbus();
function MyApp() {
return {
usrAuth: function() {
m.route(document.body, "/", {
"/": { view: () => m("p", "hello")}
})
},
usrNotAuth: function() {
m.route(document.body, "/", {
"/": { render: v => m(WelcomePage, eventbus) }
})
},
oninit: function(vnode) {
vnode.state.user = new User();
eventbus.subscribe({
type: "login",
handle: function(action) {
vnode.state.user.token = action.token;
console.log(JSON.stringify(vnode.state.user));
}
});
},
view: function(vnode) {
if(vnode.state.user.token) {
this.usrAuth();
} else {
this.usrNotAuth();
}
}
}
};
m.mount(document.body, MyApp);
MyApp is the main component. It check if user has a token, then return the proper route. This is the component that is in charge to let users login:
const m = require("mithril");
const hellojs = require("hellojs");
function TopBar(node) {
var bus = node.attrs.eventbus;
function _login() {
hellojs('facebook').login({scope:'email'});
}
return {
oninit: function(vnode) {
hellojs.init({
facebook: XXXXXXX,
}, {
redirect_uri: 'http://localhost'
});
hellojs.on('auth.login', auth => {
var fbtoken = auth.authResponse.access_token;
m.request({
method:"POST",
url:"./myapp/login/fb/token",
data:auth.authResponse,
background: true
}).then(function(result){
console.log(result);
bus.publish({ type: "login", token: result.jwttoken });
m.route.set("/");
}, function(error){
console.log(error);
bus.publish({ type: "login", token: "" });
});
});
},
view: function(vnode) {
return m("div", [
m("button", { onclick: _login }, "Login")
]);
}
}
}
export default TopBar;
TopBar component occurs in the WelcomePage component mentioned in the main one. TopBar renders a button and use hello.js to login. It uses the EventBus bus parameter to tell main component user logged in (there is an handler in main component to update the user model). Once user logins, event is fired and main component updates the user model. Good. Now, how can trigger the main component to load the right route?
I read mithril'docs again and I found that RouteResolvers perfectly suit my needs. Here is an example:
var App = (function() {
var login;
function isLoggedIn(component) {
if(login) {
return component;
} else {
m.route.set("/hey");
}
}
return {
oninit: function(vnode) {
EventBus.subscribe({
type: "login",
handle: function(action) {
console.log("incoming action: " + JSON.stringify(action));
login = action.value;
}
});
},
oncreate: function(vnode) {
Foo.eventbus = EventBus;
Bar.eventbus = EventBus;
Hey.eventbus = EventBus;
m.route(document.body, "/hey", {
"/foo": {
onmatch: function(args, requestedPath, route) { return isLoggedIn(Foo); }
},
"/bar": {
onmatch: function(args, requestedPath, route) { return isLoggedIn(Bar); }
},
"/hey": Hey
});
},
view: function(vnode) {
return m("div", "home..");
}
};
})();
Eventbus is used to let components communicate with App. They fire events (login type events) that App can handle. I found convenient to pass Eventbus the way oncreate method shows, I can use Eventbus in each component's oncreate to let components fire events.

Categories

Resources