Is there a way to remove object in the datalayer? As seen on the picture, there are two 'google_tag_params' object. I just need one. First push is onload then the second push on dataLayer in a js call. I need to remove the pushed one first before pushing the second so there is no duplicate 'google_tag_params' in the data layer
dataLayer.push(
{ "google_tag_params":google_tag_params,
"ecomm_prodid":document.getElementById('prodid').value,
"ecomm_pagetype": document.getElementById('pageType').value,
"ecomm_totalvalue": price.toFixed(2),
});
Use Array Filter
//es6
dataLayer = dataLayer.filter(x=>!x.google_tag_params);//removes any object
// which has a key google_tag_params, guessing that its value won't be falsy
// better use x => !(google_tag_params in x)
dataLayer.push(newGoogleTagParam);
//es5
dataLayer = dataLayer.filter(function (x) {
return !x.google_tag_params;
});
dataLayer.push(newGoogleParam);
You can remove data from the data layer by setting the key to an undefined value. Example:
window.dataLayer.push(function(){ this.set('google_tag_params') });
Note, in your scenario google_tag_params might be pushed twice for good reason. And as long as both objects contain all relevant data for their respective tags, each tag will fire with the relevant data. But if you want to be absolutely sure the second isn't inheriting data from the first, you can run the above code in between pushes to clear that key's data.
Related
I have a vue application that gets a set of objects from an external REST API.
In a component, I sort and filter the object into an array of objects based on a field called rank, like this:
let myResults = _.orderBy(this.search_result, 'rank', 'desc').filter(service => (service.rank >= 5) ? service: "");
I then need to move a single element/object to the end of the list before rendering it, however, when I tried to do this:
let index = myResults.findIndex(e => e.name === 'Target Element');
myResults.push(myResults.splice(index,1));
It didn't work; It pushed an empty element back to the list. Eventually, I got it working by doing the following:
myResults.push(myResults.splice(index,1)[0]);
I noticed the splice was creating an array that looked like [object, object] with all the target object in the zero index object.
I don't really understand why this happened. Have I done something to the original object somewhere or is this a vue thing?
JavaScript Array.prototype.splice() returns an Array.
Return value
An array containing the deleted elements.
If only one element is removed, an array of one element is returned.
If no elements are removed, an empty array is returned.
Since an Array is returned, you're .push()-ing and Array into an existent array. As you noticed correctly, you need to extract that one Object using removedItems[0], making
myResults.push(myResults.splice(index,1)[0]);
or equally
// Remove from array 1 item
const removedItems = myResults.splice(index, 1); // Array of removed items
// Get the first Object from array
const item = removedItems[0]; // Object
// Append one Object
myResults.push(item);
the correct approach.
Simple. I have this array and I am trying to add a value to it but when I use push it just returns the length of the array after I push the value. I remember finding a way around this with a different function but I cannot remember what it was.
I will give a bit of context:
function submitCommentHandler() {
firestore.collection("posts").doc(title).update({
comments: comments.concat(newComment)
})
navigate("/all-posts");
}
There is the function to add a comment, but when I run that function it changes the value of comments in the firestore db to a number instead of the full array. If the value of the comments changes to a number I cannot access the text within the comments.
I decided to just do comments.push(newComment) and then set the comments to comments in the object. I think thats what some people were telling me.
When you use push() to add a value to an array, the value is pushed to the original array.
const values = [1];
const pushValue = values.push(2);
console.log(pushValue); // 2
console.log(values); // [1, 2]
How can I store the output of a filter() function in an array or string to later use in another function?
jQuery('.marca').change(function(){
var regex = new RegExp(/^2x\d$/);
if(jQuery(this).find('input').prop("checked")) {
jQuery(this).nextAll().filter(function() {
// I would like to save the output from this .filter
// function to use to make a string of classes to pass to the next function.
console.log(this.className.match(regex)); //output below
return this.className.match(regex);
})
.show();
} else {
jQuery(this).nextAll().hide();
}
});
I use the above code to check the classes of a form with checkboxes and display a "subclass" only if the previous button was checked.
I use regex and filter() to find and display the next set of classes and I want to pass the resulted classes in the next jQuery selector to avoid manually adding them.
Hope I'm making some sense. Here is a fiddle with the entire code for a better understanding - https://jsfiddle.net/srjjj/brtp8x2h/9/
I have tried to simply add the result in a variable, but it won't store the entire set of values but only the last one (.2x4).
Here is the above console.log output and I guess the reason it's not working is because this is not an array of arrays but 4 different arrays but I'm not sure what to do next and how to save all of them in a variable.
console.log output
Have you tried declaring an array outside of the filter function and then pushing values in that array?
var matched = [];
jQuery(this).nextAll().filter(function () {
matched.push(yourFilteredElement);
});
I am having an array of objects where all objects have the same keys except the last object. Think like array have values and to denote all these values as a whole I have a key I am pushing the key at last along with the values in the array.
homeTask is a list of object which is the values and homeTaskKey is the key to represent the homeTask
res.data.resultSet.homeTask.forEach(element => {
var singleEvent={
task:'',
taskDuration:'',
status:'',
};
singleEvent.task=element.task;
singleEvent.taskDuration=element.taskDuration;
singleEvent.status=element.status;
newEvents.push(singleEvent);
});
newEvents.push(res.data.resultSet.homeTaskKey);
addEvent(newEvents);
}
addEvent is props method of parent component where I am setting the array to state variable name as events which is array type.
When I iterate over events using map I want to skip the last object since it does not have keys like task, taskDuration and status. Therefore it won't give any problem when I fetch those values.
events.slice(0, events.length-1).map(<function>);
this will ignore the last element and all n-1 entries will be fed to map
UPDATE:
the array name is events not event therefore it should be events.length
You could still use map, but simply pop the last element off once the map completes. For example:
const newEvents = homeTask.map(({ task, taskDuration, status }) => ({
task, taskDuration, status
}))
newEvents.pop()
addEvent(newEvents)
Or just replace the last item with your taskkey, as you know the last item will be junk:
newEvents[newEvents.length - 1] = res.data.resultSet.homeTaskKey
Or just slice the array prior to mapping, and then push the taskKey at the end like you were doing. slice is safe to perform on your prop, as it shallow copies.
Or most importantly, ask yourself why you have this entirely weird data structure that has the key appended on the end. Perhaps rethink your data and not create this problem for yourself in the first place.
res.data.resultSet.homeTask.forEach((element,index) => {})
second param to function is index you, can use this to identify the second last element by comparing it with total length of array.
hmm you can try with this
res.data.resultSet.homeTask.forEach(element => {
if(!element.task)
return false;
...bla bla bla
}
The map() method creates a new array with the results of calling a function for every array element.
So it creates an array of same length from source array.
What you need is filter()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Something like this;
const tasks = res.data.resultSet.homeTask.filter((element) => {
const { task, taskDuration, status } = element;
return task && taskDuration && status;
});
I'm making a Google Chrome Extension that uses context menus as its main UI. Each menu item triggers the same content script, but with different parameters. What I basically did is store every item (and its corresponding data) in the form of a JSON object that has the following form :
{name, parent_id, rule_number, meta_array[], childCount}
name, child_count and parent_id are used to create the hierarchy when the context menus are built. The data that's passed to the script is rule_number (int) and meta_array (array of strings). All of these objects are stored into an array called indexData[].
When a menu item is clicked, the id provided is just used as an index in the "indexData" array to get the right data and pass it to the script.
For example:
// Iterates through the objects
for(var j = 0; j < objectsArray.length; j++) {
// Context menu created with unique id
var id = chrome.contextMenus.create({
"title": objectArray[j].name,
"onclick": injectScript,
"parentId": objectsArray[j].parent_id });
// Stores the objects at the corresponding index
indexData[id] = objectsArray[j]; }
Now, there was a particular large set of data that comes back often. Instead of listing every single of these elements every time I wanted them as part of my menu, is just added a boolean parameter to every JSON object that needs this set of data as its children. When the menus are created, a function is called if this boolean is set to true. The script then just iterates through a separate list of objects and makes them children of this parent object. The created children even inherit certain things from the parent object.
For example, if a parent object had a meta_array like such ["1", "2", "3", "4"], its children could all look like so ["1", "2", custom_children_data[3], "4"].
The problem is that this last part doesn't work. While the children are created just fine and with the right name, the data that's associated with them is wrong. It's always going to be the data of the last object in that separate list. This is what the function looks like:
// Iterate through children list
for(var i = 0; i < separateList.length; i++){
// Just copying the passed parent object's data
var parentData = data;
var id = chrome.contextMenus.create({
"title": separateList[i].name, // Get item [i] of the children list (works fine)
"onclick": injectScript,
"parentId": parentId // Will become a child of parent object
});
// Trying to change some data, this is where things go wrong.
parentData.meta[2] = separateList[i].meta;
// Save in indexData
indexData[id] = parentData; }
On the loop's first iteration, parentData.meta[2] gets the right value from the list and this value is thereafter saved in indexdata. But on subsequent iterations, all the values already present in indexData just get swiped away and replaced by the latest data being read from the list. When the last value is read, all the newly added elements in indexData are therefore changed to that last value, which explains my problem. But why on earth would it do that ? Does Java somehow treat arrays by address instead of value or something in this case ?
Maybe I'm missing something really obvious, but after many attempts I still can't get this to work properly. I tried to be as specific as possible in my description, but I probably forgot to mention something, so if you want to know anything else, just ask away and I'll be happy to provide more details.
Thanks.
The problem would be indexData[id] = parentData where you are making indexData[id] a reference to parentData, and then modifying parentData on the next iteration of your loop.
Since parent data is not a simple array (It contains at least one array or object), you cannot simply use slice(0) to make a copy. You'll have to write your own copy function, or use a library which has one.
My guess is that this is where your problem lies:
// Just copying the passed parent object's data
var parentData = data;
This does not, in fact, copy the data; rather, it creates a reference to data, so any modifications made to parentData will change data as well. If you're wanting to "clone" the data object, you'll have to do that manually or find a library with a function for doing so.