concatenate dataLayer for impression tracking because of lazyloading - javascript

I want to implement impression tracking on element visibility. I am following the guide of simo ahava
https://www.simoahava.com/analytics/true-view-impressions-google-tag-manager/
Now I cannot replicate that example because it needs to fire all product once into the dataLayer but on my case i am doing lazy loading and have to push the product in batch into the dataLayer. Unfortunately by doing this every time we are pushing some element into the datalayer it will only take the last values of the event push on google tag manager so it is very possible that the product becomes visible but is no more available into the dataLayer.
Here is a more detailed explanation
Step 1 : We have a two push into the data layer for lazy loading purpose
1a. first push as the first portion loads
dataLayer=[];
dataLayer.push({
event: 'eec.impressionView',
"ecommerce": {
"currencyCode": "USD",
"impressions": [{
"id": "9bdd2",
"name": "Compton T-Shirt",
"price": "44.00",
"brand": "Compton",
"category": "T-Shirts",
"position": 0,
"list": "shirts you may like"
},
{
"id": "239b5",
"name": "Pigzart T-Shirt",
"price": "82.00",
"brand": "Pigzart",
"category": "T-Shirts",
"position": 1,
"list": "shirts you may like"
}
],
}
});
1b. second push due to lazy loading
dataLayer.push({
event: 'eec.impressionView',
"ecommerce": {
"currencyCode": "USD",
"impressions": [
{
"id": "7w9e0",
"name": "Masons T-Shirt",
"price": "31.00",
"brand": "Masons",
"category": "T-Shirts",
"position": 2,
"list": "shirts you may like"
},
{
"id": "57b9d",
"name": "Kiosk T-Shirt",
"price": "55.00",
"brand": "Kiosk",
"category": "T-Shirts",
"position": 3,
"list": "shirts you may like"
}
],
}
});
2 - Now let's say that the customer have an element visibility trigger that happen after the second dataLayer push on the product "Compton T-Shirt". It will not be able to know what are the information
So comes my questions , is there a way to concatenate the eec.impressionView events into a single one on the GTM side or is there a better way to handle this type of problem to be able to capture the impression

What you're encountering is known as "Recursive Merge", so the products you're pushing into the dataLayer merge in with the existing products in the internal data model, rather than being appended to it.
The easiest way to avoid the recursive merge is within your dataLayer push.
Instead of doing a full dataLayer push for your subsequent impressions
dataLayer.push({
event: 'eec.impressionView',
"ecommerce": {
"currencyCode": "USD",
"impressions": [
{
"id": "7w9e0",
"name": "Masons T-Shirt",
"price": "31.00",
"brand": "Masons",
"category": "T-Shirts",
"position": 2,
"list": "shirts you may like"
},
{
"id": "57b9d",
"name": "Kiosk T-Shirt",
"price": "55.00",
"brand": "Kiosk",
"category": "T-Shirts",
"position": 3,
"list": "shirts you may like"
}
],
}
});
It works if you can use this for the subsequent dataLayer pushes.
dataLayer.push(['ecommerce.impressions.push',
{
"id": "7w9e0",
"name": "Masons T-Shirt",
"price": "31.00",
"brand": "Masons",
"category": "T-Shirts",
"position": 2,
"list": "shirts you may like"
},
{
"id": "57b9d",
"name": "Kiosk T-Shirt",
"price": "55.00",
"brand": "Kiosk",
"category": "T-Shirts",
"position": 3,
"list": "shirts you may like"
}]);
This will prevent the second push from overwriting the existing values and because you're using visibility triggers there's no need for the repeated event, and everything else will be the same in the data model.
Alternatively you could use a custom HTML tag and fire that on each event to store the impressions in a separate JS object and reference that rather than the dataLayer in your Enhanced Ecommerce setup.

Related

How to return results that combine themselves from an attribute the is equal?

I have a database of musical works and in these works the are information about the owners of that works. The owner can be an editor or a composer. There can be many composers and many editors.
Editors and composers have a publishing relationship that is indicated by their attribute called link. So, if an editor has a link = 5 and the composer too, they are linked. Or the editor is the publisher of that composer.
I use this query to get only the musical works that are from the editor I want.
db.works.find({'pro_owners.codigo_ecad': 5546730})
.projection({})
.sort({_id:-1})
.limit(100)
And it retrieves me some documents like these:
{
"_id": "6042617f0732f22da210e7a6",
"codigo_ecad": 16403107,
"iswc": "T0401990268",
"titulo": "YA INTENTE COMPREENDER",
"situacao": "LB",
"data_inclusao": "2017-06-02T03:00:01.000Z",
"pro_owners": [
{
"codigo_ecad": 8096286,
"owner": "JOSIEL DEL CID",
"category": "CA",
"percent": 0,
"link": "2",
"_id": "60426160dca0dd0dc8290d41"
},
{
"codigo_ecad": 381928,
"owner": "THALES ROBERTO DA SILVA",
"category": "CA",
"percent": 0.75,
"link": "1",
"_id": "6042615bdca0dd0dc8290d32"
},
{
"codigo_ecad": 5546730,
"owner": "THALES ROBERTO DA SILVA - EIRELI - ME",
"category": "E",
"percent": 0.25,
"link": "1",
"_id": "6042615bdca0dd0dc8290d33"
}
],
"client_name": "Datha Editora"
}
I would like to know if there is a way query and receive only the unique linked owners of the editor I am interested in. In the above case, just:
{
"codigo_ecad": 381928,
"owner": "THALES ROBERTO DA SILVA",
"category": "CA",
"percent": 0.75,
"link": "1",
"_id": "6042615bdca0dd0dc8290d32"
}
The next step would be a $lookup to the owners collection to return these results with their full data. But it is a plus.
You can accomplish that with aggreation:
$match to select only document containing a pro_owner with the matching code
$addFields with $filter to extract the matching pro_owner into a new field
$addFields/$project with $filter to limit the pro_owners list to those with the same link value as the new field

API call with Axios filtering response.data

I want to get the newest 8 products depend on product's date. I can get the whole products array and filter it as you see below:
const newestProducts= [];
axios.get("http://localhost:3003/products").then(response => {
let products = response.data.sort(function(a, b) {
return new Date(b.date) - new Date(a.date);
});
newstProducts = product.slice(0,7)
});
but this will be so bad if I have thousands of product, and I just need to get the newest 8 Products only
I thought about adding ?_limit=8 to the call
axios.get("http://localhost:3003/products?_limit=8").then{...}
but this also doesn't work propersly as you know because it gets me the only top 8 products of the array
Is there any way to filter the products before I get it from the server or I MUST store them all in var and then filter them
The Json File
"categories": [
{
"id": 9,
"category": "bathroom",
"date": "2020/8/3",
"name": "ullam basin mixer",
"price": 160,
"img_1": "rim_mixer_01.jpg",
"img_2": "rim_mixer_02.jpg",
"rating": 4.5,
"description": "MARMO is a complete series made of 72 models, with different shapes and sizes for different functions, that keeps uncompromised its elegant beauty. This is a Demo Online Store."
},
{
"id": 10,
"category": "bathroom",
"date": "2020/8/19",
"name": "gravida bathtub",
"price": 2100,
"img_1": "inbani_bathtub_01.jpg",
"img_2": "inbani_bathtub_02.jpg",
"rating": 4,
"description": "A young company with a wealth of experience. created in 2004, inbani has evolved into a leader in innovation thanks to a conviction to create products which truly benefit the well-being of the customer. This is a Demo Online Store. No orders shall be fulfilled."
},
{
"id": 11,
"category": "bathroom",
"date": "2020/9/9",
"name": "vulputate mixer",
"price": 300,
"img_1": "marmo_mixer_01.jpg",
"img_2": "marmo_mixer_02.jpg",
"description": "MARMO is a complete series made of 72 models, with different shapes and sizes for different functions, that keeps uncompromised its elegant beauty. This is a Demo Online Store."
},
{
"id": 12,
"category": "bathroom",
"date": "2018/7/17",
"name": "aliquam veneatis bathtub",
"price": 2580,
"img_1": "sa_oche_01.jpg",
"img_2": "sa_oche_02.jpg",
"description": "Its oval, elliptical design with the incongruent walls invokes an avant-garde atmosphere in the bathroom."
},
{
"id": 13,
"category": "kitchen",
"date": "2020/3/13",
"name": "quisque teapot",
"price": 240,
"img_1": "theo_teapot_01.jpg",
"img_2": "theo_teapot_02.jpg",
"description": "Theo Teapot is a Scandinavian-Japanese teapot made from stoneware and bamboo, designed by Unit 10 Design for Stelton. This is a Demo Online Store. No orders shall be fulfilled."
},
{
"id": 14,
"category": "kitchen",
"date": "2020/2/12",
"name": "creamic teapot",
"price": 60,
"img_1": "cer_teapot_01.jpg",
"img_2": "cer_teapot_02.jpg",
"rating": 3.9,
"description": "Matte ceramic tea pot comes with integrated and removable metal tea infuser. Capacity 700 ml (2.96 cups). Dishwasher safe. This ceramic teapot has a white matte finish, coupled with a square shape and curved lines."
},
{
"id": 15,
"category": "kitchen",
"date": "2019/2/1",
"name": "bottle grinders",
"price": 30,
"img_1": "bottle_gringer_01.jpg",
"img_2": "bottle_gringer_02.jpg",
"rating": 4.8,
"description": "Bottle Grinders is a minimal, timeless salt and pepper mill set designed by Norm.Architects for Menu. Steering away from the predictable grinder, the Norm Bottle Grinder is not what you expect to see in a salt and pepper grinder. The form, shaped more like a bottle, cleverly tricks the user to encourage a more playful and experimental interaction with the product. This is a Demo Online Store. No orders shall be fulfilled. Purchase this product"
},
{
"id": 16,
"category": "lighting",
"date": "2020/1/3",
"name": "commodo blown lamp",
"price": 275,
"img_1": "tradition_blown_01.jpg",
"img_2": "tradition_blown_02.jpg",
"description": "Blown lamp SW3 & SW4 by &tradition is a mouth-blown pendant lamp with a quilted pattern, it comes in a translucent variant with a silver lustre or in a opal white version. Blown lamp is fitted with a powder-coated metal suspension. This is a Demo Online Store. No orders shall be fulfilled."
},
{
"id": 17,
"category": "lighting",
"date": "2020/6/9",
"name": "spot table",
"price": 100,
"img_1": "spot_lamp_01.jpg",
"img_2": "spot_lamp_02.jpg",
"rating": 3.4,
"description": "Set the stage. The Spot lamp is a lively, versatile addition to your room. This is a Demo Online Store. No orders shall be fulfilled."
}
]
The problem is not in API Calling... To enhance the performance you have to refractor the DATABASE REQUEST in the backend to get the last 8 products only.
Note:
You make this through the query you send to the database in the controller (ROUTE ) in the backend

How to use multiple attributes in algolia search using Django . Show multiple courses

How to use multiple attributes in algolia search using Django . Show multiple courses
{
"course_": [
{
"interest_min": 11,
"other_fees": 0,
"tution_fees": 56000,
"interest_max": 14,
"duration_max": 7,
"payment_month_min": 4573,
"total": 56000,
"payment_month_max": 2567,
"course_name": "Mtech",
"hostel_fees": 0,
"duration_min": 5,
"course_type": "Full Time",
"duration": "4"
},
{
"interest_min": 7,
"other_fees": 465,
"tution_fees": 35456,
"interest_max": 14,
"duration_max": 5,
"payment_month_min": 2414,
"total": 41385,
"payment_month_max": 483,
"course_name": "Mca",
"hostel_fees": 5464,
"duration_min": 2,
"course_type": "Full Time",
"duration": "2"
}
],
"name": "A. K. Choudhury School Of Information Technology, Kolkata",
"slug": "a-k-choudhury-school-of-information-technology-kolkata",
"country": "India",
"location_type": "Domestic",
"type": "College",
"address": "Kolkata",
"image": "images/a-k-choudhury-school-of-information-technology-kolkata_M9cCiHQ.jpg",
"institute_type": "Private",
"cities": "noida",
"college_facilities": "Sports Transportation",
"approved_by": "University Of Calcutta, Kolkata",
"established": "2005-01-05",
"state": "Up",
"objectID": "2"
}
How to use multiple attributes in algolia search using Django . Show multiple courses
using instantsearch.js in django
If you are searching from your Django back-end, you should use the raw_search method to search within your data and get the corresponding JSON.
You can then loop over the course_ attribute to display the school's courses:
On the other hand, if you want to search from your frontend with instantsearch.js, you should follow the Getting Started Guide: have a look at the Display Results section which explains how you can use a Mustache template to display all the attributes you want from your records.

Append '|' after every array element

I have this JSON & what I want to do is to make genres like this action|adventure|comedy
{
"id": 1,
"key": "deadpool",
"name": "Deadpool",
"description": "A former Special Forces operative turned mercenary is subjected to a rogue experiment that leaves him with accelerated healing powers, adopting the alter ego Deadpool.",
"genres": [
"action",
"adventure",
"comedy"
],
"rate": 8.6,
"length": "1hr 48mins",
"img": "assets/images/movie-covers/deadpool.jpg"
},
{
"id": 2,
"key": "we-are-the-millers",
"name": "We're the Millers",
"description": "A veteran pot dealer creates a fake family as part of his plan to move a huge shipment of weed into the U.S. from Mexico.",
"genres": [
"adventure",
"comedy",
"crime"
],
"rate": 7,
"length": "1hr 50mins",
"img": "assets/images/movie-covers/we-are-the-millers.jpg"
}
my component code snippet
data => {
this.movies = data;
var tempArr= data
var genres;
let genresWithPipe=[];
let len= tempArr.length;
for(var i=0; i<len; i++){
genres=tempArr[i].genres+'|';
// console.log(tempArr[i].genres)
for(var j=0;j<genres.length; j++){
if(j<genres.length-1)
genres[j]= genres[j]+'|';
console.log(genres,data);
//genresWithPipe=genres;
}
}
console.log(this.movies,genres)
}
I have tried to do it with the help of for loop in my component but then when I am displaying it in the html with the help of *ngFor then because it's a local variable,it won't show up. If I store array values in a global variable then the variable only store the last array.
You can use map method in order to achieve your requirement and obtain a more cleaner solution.
The map() method creates a new array with the results of calling a
provided function on every element in the calling array.
Also, you can use join method in order to obtain the structure action|adventure|comedy with | delimiter.
let array=[{ "id": 1, "key": "deadpool", "name": "Deadpool", "description": "A former Special Forces operative turned mercenary is subjected to a rogue experiment that leaves him with accelerated healing powers, adopting the alter ego Deadpool.", "genres": [ "action", "adventure", "comedy" ], "rate": 8.6, "length": "1hr 48mins", "img": "assets/images/movie-covers/deadpool.jpg" }, { "id": 2, "key": "we-are-the-millers", "name": "We're the Millers", "description": "A veteran pot dealer creates a fake family as part of his plan to move a huge shipment of weed into the U.S. from Mexico.", "genres": [ "adventure", "comedy", "crime" ], "rate": 7, "length": "1hr 50mins", "img": "assets/images/movie-covers/we-are-the-millers.jpg" }];
array=array.map(function(item){
item.genres=item.genres.join('|');
return item;
});
console.log(array);
A good solution with Array.map() has been proposed, here is another option with Array.forEach():
const data = [{
"id": 1,
"key": "deadpool",
"name": "Deadpool",
"description": "A former Special Forces operative turned mercenary is subjected to a rogue experiment that leaves him with accelerated healing powers, adopting the alter ego Deadpool.",
"genres": [
"action",
"adventure",
"comedy"
],
"rate": 8.6,
"length": "1hr 48mins",
"img": "assets/images/movie-covers/deadpool.jpg"
},
{
"id": 2,
"key": "we-are-the-millers",
"name": "We're the Millers",
"description": "A veteran pot dealer creates a fake family as part of his plan to move a huge shipment of weed into the U.S. from Mexico.",
"genres": [
"adventure",
"comedy",
"crime"
],
"rate": 7,
"length": "1hr 50mins",
"img": "assets/images/movie-covers/we-are-the-millers.jpg"
}
]
const genres = [];
data.forEach(film => genres.push(film.genres.join("|")));
console.dir(genres);
Note that your data definitely doesn't look like what you put in the code sample, it must be wrapped with [].

Cannot access array objects when that array is itself an attribute of an object

I am unable to access an array of objects that is itself an attribute of a larger object.
console.log(skillprofiles);
console.log(skillprofiles.skills);
The above statements return an array of two objects that each have an attribute that is a, seemingly, valid array of objects ("skills" in this example).
I am unable to access the "skills" array attribute. The data I am ultimately trying to get at is the "item_name" attribute. As far as I know, that should be accessible via:
skillprofiles[0].skills[0].item_name
Interestingly enough, verifying the type of the "skills" attribute with "typeof" returns "object" instead of array. This could be because I am transferring an array of objects from one object to another earlier in my code. I thought I was doing this properly and seemed to have confirmed that by my logging statements.
UPDATE with actual data:
[{
"skillprofile_id": 144,
"skillprofile_name": " On-boarding",
"start_date": "January 30 2012",
"progress": 0,
"complete_date": " ",
"category": 1053,
"skills": [{
"category": "Acquire: Onboard New Hires",
"item_name": "3. On-boarding a New Hire - Day 1",
"skill_type": "activity",
"object_id": 68,
"duration": "8:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}, {
"category": "Acquire: Onboard New Hires",
"item_name": "4. On-boarding Checklist",
"skill_type": "activity",
"object_id": 67,
"duration": "1:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}]
}, {
"skillprofile_id": 143,
"skillprofile_name": " Setting Up Systems",
"start_date": "January 30 2012",
"progress": 0,
"complete_date": " ",
"category": 1053,
"skills": [{
"category": "Acquire: Onboard New Hires",
"item_name": "1. Office Organization",
"skill_type": "activity",
"object_id": 65,
"duration": "4:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}, {
"category": "Acquire: Onboard New Hires",
"item_name": "2. Welcome to the Team Documents",
"skill_type": "activity",
"object_id": 66,
"duration": "2:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}, {
"category": "Acquire: Onboard New Hires",
"item_name": "3. Welcome Documents: Feedback ",
"skill_type": "activity",
"object_id": 150,
"duration": "1:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}]
}]
UPDATE 2:
Given the responses so far, it seems that I should be able to run the following:
$.each(skillprofiles, function(){
console.log(this.skills)
});
I can do this from the console, but the console statements come back as "undefined" when run from my code
In your first block of code, skills is directly a child of skillprofiles. Whereas in the second one, you write skillprofiles[o].skills. If the first one works, maybe your code should be:
skillprofiles.skills[0].item_name
With that data structure, the proper access would be:
skillprofiles[i].skills[j].item_name
You can see it work here: http://jsfiddle.net/jfriend00/wPLZZ/
skillprofiles is an array of objects so you get an object from the array with:
skillprofiles[i]
Each object in that array, has a number of properties and one of those properties is named skills so you would get that property with
skillprofiles[i].skills
The contents of the skills property is another array so you would get an item from that aray with this:
skillprofiles[i].skills[j]
That array holds objects with their own properties so you would access a specific property with this:
skillprofiles[i].skills[j].item_name

Categories