HowTo?: itemDetails.reduce is not a function - javascript

So, I'm attempting to reduce a returned graphql object (See attached image) as follows:
var quantity = itemDetails.reduce((a, itemvariants) => a + itemvariants.quantity, 0);
I get the above mentioned error message. What am I overlooking here?

You're calling reduce on the object, not the itemVariants array.
quantity = itemDetails.itemVariants.reduce((a, variant) => a + variant.quantity, 0);

looks like you want to reduce the items from itemVariants, not itemDetails
let quantity = itemDetails.itemVariants.reduce((total, variant) => total + variant.quantity, 0)

Related

how to get to the key in an array of objects?

I hope you are all well 🙂
I would like to ask something that (I hope) is basic, i have this function that is responsible for returning the filtered objects with a specific "key" variable that translates to color or size.
Well I put the color and size variables inside an array of objects, I would like to know what is the terminology I have to use now in my "item[key]" to be able to get to my "color" variable as shown in the last picture 😦
picture showing what key im able to get now and then what key im looking to get!
Thanks in advance for any and all help, have a nice day!
here is the code for the two functions used in this process:
const [filtros,setFiltros] = useState({});
const gerirFiltros = (evento) =>{
const valor = evento.target.value;
console.log(evento.target.name + evento.target.value)
if (evento.target.name === "cor" ) {
const cor = evento.target.name
setFiltros( {
...filtros,
["variacoes"]:[{
[evento.target.name]:valor
}],
})
}
else {
setFiltros({
...filtros,
[evento.target.name]:valor,
}) // THIS IS JUST TO PASS TO PAGE #2 (https://pastebin.com/4GH3Mi3H) THE VARIABLE `filtros` THAT IS AN ARRAY WITH MANY FILTERS LIKE -> {marca:"Paz rodrigues"}, etc..
And the functio that receives the filter ( the one i think i need to change) :
useEffect(() => {
categoria &&
setProdutosFiltrados(
produtos.filter((item) =>
Object.entries(filtros).every(([key,value],i) =>
//console.log("key ->" + key + "value->" + value[0].cor) )
item[key].includes(value)
)
)
)
You can use some()
useEffect(() => {
categoria &&
setProdutosFiltrados(
produtos.filter((item) =>
Object.entries(filtros).every(([key,value],i) =>{
//Here the value is an array 'variacoes' so to check colors use filter to get all the elements of 'variacoes' array;
//Also assuming that the color you are passing will be available here as item[key]
var allColors = item.map(i=>i.cor)
return value.some((val)=>allColors.includes(val.cor))
}
)
)
)

push only unique values into array

not able to check the unique values log showing all values getting
added to the array
.
var moveToReady = [];
var topLinesRecords = new GlideRecord('x_snc_ms_dynamics_d365_queue');
topLinesRecords.addEncodedQuery('root_element_sys_id=03133e1a1bfe6410f8ca0e16624bcba7');
topLinesRecords.orderByDesc('sys_created_on');
topLinesRecords.query();
while(topLinesRecords.next()){
gs.info(' first record : ' + topLinesRecords.number);
if(moveToReady.indexOf(topLinesRecords.getValue('object_sys_id')) == -1){
moveToReady.push(topLinesRecords.getValue('object_sys_id'));
}
gs.info('array. : ' + moveToReady);
updateRecordtoFail(topLinesRecords);
}
You can use the Set structure from ES6 to make your code faster and more readable:
// Create Set
this.items = new Set();
add(item) {
this.items.add(item);
// Set to array
console.log([...this.items]);
}
you may use array.includes
if (!moveToReady.includes(topLinesRecords.getValue('object_sys_id'))){
moveToReady.push(topLinesRecords.getValue('object_sys_id'));
}
So, some tips to get unique values on ServiceNow:
-GlideRecord has a "getUniqueValue" method
(URL: https://docs.servicenow.com/bundle/paris-platform-administration/page/administer/table-administration/concept/c_UniqueRecordIdentifier.html)
-You can search on your Script Includes a OOB method/function to get only unique values. Search for "utils". Every instance has this, maybe "ArrayUtils".
Hope this information helped!

How do I use javascript includes to filter out text that does not include specific text

I have a method that gets a list of saved photos and determines the number of photos listed. What I wish to do is return the number of photos that contain the text "Biological Hazards" in the name. Here is my code so far
getPhotoNumber(): void {
this.storage.get(this.formID+"_photos").then((val) => {
this.photoResults = JSON.parse(val);
console.log("photoResults", this.photoResults);
// photoResults returns 3 photos
// Hazardscamera_11576868238023.jpg,
// Biological Hazardscamera_11576868238023.jpg,
// Biological Hazardscamera_11576868351915.jpg
this.photoList = this.photoResults.length;
console.log("photoList", this.photoList); // returns 3
this.photoListTwo = this.photoResults.includes('Biological Hazards').length; // I wish to return 2
}).catch(err => {
this.photoList = 0;
});
}
Any help would be greatly appreciated.
Xcode log
[
One way to do this is to .filter() the array, and then calculate the length of that array.
this.photoListTwo = this.photoResults.filter(photoString => {
return photoString === 'Biological Hazards' //or whatever comparison makes sense for your data
}).length;
Quick solution for this (sorry for the lack of better formating, posting from mobile):
const array = ["Hazardscamera_11576868238023.jpg", "Biological Hazardscamera_11576868238023.jpg", "Biological Hazardscamera_11576868351915.jpg"];
const filterBioHazards = (str) => /Biological Hazards/.test(str);
console.log(array.filter(filterBioHazards).length);
// Prints 2
The method includes returns boolean to indicate whether the array contains a value or not. What you need is to filter your array and return its length after.
You need to replace the line:
this.photoListTwo = this.photoResults.includes('Biological Hazards').length;
By this:
this.photoListTwo = this.photoResults.filter(function(result) {return result.contains("Biological Hazards");}).length;

Javascript's method forEach() creates array with undefined keys

I am building a simple todo app, and I'm trying to get the assigned users for each task. But let's say that in my database, for some reason, the tasks id starts at 80, instead of starting at 1, and I have 5 tasks in total.
I wrote the following code to get the relationship between user and task, so I would expect that at the end it should return an array containing 5 keys, each key containing an array with the assigned users id to the specific task.
Problem is that I get an array with 85 keys in total, and the first 80 keys are undefined.
I've tried using .map() instead of .forEach() but I get the same result.
let assignedUsers = new Array();
this.taskLists.forEach(taskList => {
taskList.tasks.forEach(task => {
let taskId = task.id;
assignedUsers[taskId] = [];
task.users.forEach(user => {
if(taskId == user.pivot.task_id) {
assignedUsers[taskId].push(user.pivot.user_id);
}
});
});
});
return assignedUsers;
I assume the issue is at this line, but I don't understand why...
assignedUsers[taskId] = [];
I managed to filter and remove the empty keys from the array using the line below:
assignedUsers = assignedUsers.filter(e => e);
Still, I want to understand why this is happening and if there's any way I could avoid it from happening.
Looking forward to your comments!
If your taskId is not a Number or autoconvertable to a Number, you have to use a Object. assignedUsers = {};
This should work as you want it to. It also uses more of JS features for the sake of readability.
return this.taskLists.reduce((acc, taskList) => {
taskList.tasks.forEach(task => {
const taskId = task.id;
acc[taskId] = task.users.filter(user => taskId == user.pivot.task_id);
});
return acc;
}, []);
But you would probably want to use an object as the array would have "holes" between 0 and all unused indexes.
Your keys are task.id, so if there are undefined keys they must be from an undefined task id. Just skip if task id is falsey. If you expect the task id to possibly be 0, you can make a more specific check for typeof taskId === undefined
this.taskLists.forEach(taskList => {
taskList.tasks.forEach(task => {
let taskId = task.id;
// Skip this task if it doesn't have a defined id
if(!taskId) return;
assignedUsers[taskId] = [];
task.users.forEach(user => {
if(taskId == user.pivot.task_id) {
assignedUsers[taskId].push(user.pivot.user_id);
}
});
});
});

firebase -> date order reverse

I am currently making an app using Firebase.
It is one of those bulletin boards that can be seen anywhere on the web.
But there was one problem.
This is a matter of date sorting.
I want to look at the recent date first, but I always see only the data I created first.
postRef.orderByChild('createData').startAt(reverseDate).limitToFirst(1).on('child_added',(data)=>{
console.log(data.val().name + data.val().createData);
})
result - >hello1496941142093
My firebase tree
My code is the same as above.
How can I check my recent posts first?
How Do I order reverse of firebase database?
The Firebase Database will always return results in ascending order. There is no way to reverse them.
There are two common workaround for this:
Let the database do the filtering, but then reverse the results client-side.
Add an inverted value to the database, and use that for querying.
These options have been covered quite a few times before. So instead of repeating, I'll give a list of previous answers:
Display posts in descending posted order
Sort firebase data in descending order using negative timestamp
firebase sort reverse order
Is it possible to reverse a Firebase list?
many more from this list: https://www.google.com/search?q=site:stackoverflow.com+firebase+reverse%20sort%20javascript
You can simply make a function to reverse the object and then traversing it.
function reverseObject(object) {
var newObject = {};
var keys = [];
for (var key in object) {
keys.push(key);
}
for (var i = keys.length - 1; i >= 0; i--) {
var value = object[keys[i]];
newObject[keys[i]]= value;
}
return newObject;
}
This is how I solved it:
First I made a query in my service where I filter by date in milliseconds:
getImages (): Observable<Image[]> {
this.imageCollection = this.asf.collection<Image>('/images', ref => ref.orderBy('time').startAt(1528445969388).endAt(9999999999999));
this.images = this.imageCollection.snapshotChanges().pipe(
map(actions => actions.map(a => {
const data = a.payload.doc.data() as Image;
const id = a.payload.doc.id;
return { id, ...data };
}))
);
return this.images;
}
Then to get the newest date first I added this to my component where I call the method from my service:
let date = new Date;
let time = 9999999999999 - date.getTime();
console.log(time);
I pass the time let as the date. Since a newer date will be a bigger number to deduct from the 9999999999999, the newest date will turn up first in my query inside my service.
Hope this solved it for you
If you want to display it in the front end, I suggest that after you retrieve the data, use the reverse() function of JavaScript.
Example:
let result = postRef
.orderByChild("createData")
.startAt(reverseDate)
.limitToFirst(1)
.on("child_added", data => {
console.log(data.val().name + data.val().createData);
});
result.reverse();
Ive ended changing how I create my list on the frontend part.
was
posts.add(post);
changed to
posts.insert(0, post);
You could use a method where you save the same or alternate child with a negative value and then parse it.
postRef.orderByChild('createData').orderByChild('createData').on('child_added',(data)=>{
console.log(data.val().name + data.val().createData);})
Far more easier is just use Swift's reversed():
https://developer.apple.com/documentation/swift/array/1690025-reversed
https://developer.apple.com/documentation/swift/reversedcollection
let decodedIds = try DTDecoder().decode([String].self, from: value)
// we reverse it, because we want most recent orders at the top
let reversedDecodedIds = decodedIds.reversed().map {$0}
orderBy("timestamp", "desc")
I think you can give a second argument name "desc".
It worked for me

Categories