Adding href information into an array - javascript

I have an array of information and a script that should extract that information. I've tried adding a command that when onclick() it is supposed to href somewhere, but I can't quite get it to work.
The array is fetched from a repository and looks like this (link is in the code):
[
{
"id": 1,
"category": "Cat",
"desc": "Sexy",
"url": "https://www.svt.se/"
},
{
"id": 2,
"category": "Cat2",
"desc": "gg",
"url": "https://www.svt.se/"
},
{
"id": 3,
"category": "Maxwell",
"desc": "aaa",
"url": "https://www.svt.se/"
},
{
"id": 4,
"category": "Fat",
"desc": "we",
"url": "https://www.svt.se/"
}
]
I am currently trying to make a searchbar that can change the href to different websites when you click on the thing you searched on.
Here is the code:
<div class="search-wrapper">
<input type="search" id="search" data-search>
</div>
<div class="user-cards" data-user-cards-container>
<template data-user-template>
<div class="card hide" onclick="href()">
<div class="header" data-header></div>
<div class="body" data-body></div>
</div>
</template>
</div>
<script>
const userCardTemplate = document.querySelector("[data-user-template]")
const categoriesSearch = document.querySelector("[data-user-cards-container]")
const searchInput = document.querySelector("[data-search]")
let users = []
searchInput.addEventListener("input", e => {
const value = e.target.value.toLowerCase()
users.forEach(user => {
const isVisible =
user.category.toLowerCase().includes(value) ||
user.desc.toLowerCase().includes(value)
user.element.classList.toggle("hide", !isVisible)
})
})
function href() {
location.href = ""
}
fetch("https://raw.githubusercontent.com/UllestReal/Website/main/Test")
.then(res => res.json())
.then(data => {
users = data.map(user => {
const card = userCardTemplate.content.cloneNode(true).children[0]
const header = card.querySelector("[data-header]")
const body = card.querySelector("[data-body]")
header.textContent = user.category
body.textContent = user.desc
categoriesSearch.append(card)
return {
category: user.category,
desc: user.desc,
element: card
}
})
})
</script>

Related

moving a key value pair out of an array

I am trying to move everything in the Array Results outside and into the original object
this is the object
{
"Name": "John",
"Results": [
{
"Type": "DB",
"Immediate_Action": "No",
}
]
}
It should look like this
{
"Name": "John",
"Type": "DB",
"Immediate_Action": "No",
}
What I have so far is this
const mapOscarResults = ({ data }) => {
return data.map(entry => {
let mapped = {...entry};
entry.Results.forEach(key => {
let Type = mapped[key.Type]
if (mapped[key]) {
mapped[key].push(entry.Results[key]);
} else {
mapped[key] = [entry.Results[key]];
}
});
return mapped;
});
};
You can simply spread the Results array into an Object.assign() call.
const input = { "Name": "John", "Results": [{ "Type": "DB", "Immediate_Action": "No", }, { "Another": "value" }] };
const { Results, ...refactored } = input;
Object.assign(refactored, ...Results);
console.log(refactored)
This code works for your example:
const { Results: results, ...rest } = {
"Name": "John",
"Results": [
{
"Type": "DB",
"Immediate_Action": "No",
}
]
}
const res = {...rest, ...results.reduce((prev, curr) => ({
...prev,
...curr
}), {})}
console.log(res)
But I don't know what you expect when the Results array has more than one element.
In that condition, if this code does not fill your needs, ask me to change it.
however, it will join first Result with index 0, you can expand it
const data = {
"Name": "John",
"Results": [
{
"Type": "DB",
"Immediate_Action": "No",
}
]
}
const mapOscarResults = (data) => {
for (let i in Object.keys(data)){
if (Array.isArray(data[Object.keys(data)[i]])){
newKey = data[Object.keys(data)[i]][0]
data = {... data, ...newKey}
delete data[Object.keys(data)[i]]
}
}
return data
};
console.log(mapOscarResults(data))

Remove an object from an array of if not Present in Array

I have a project in React. In this Project, I have some array of users stored and I have one more array that contains message objects having three properties from, to, and message. Now I want, if the user id is not present message array then remove the user from the list. I am using Node.js as a backend. Or in simple words if the user has not sent or received any messages, then remove from them from the user list. Or if there any other solution for storing the users and messages in a single array.
users.json
[
{
"id": "1",
"name": "Rampal"
},
{
"id": "2",
"name": "Anisha"
},
{
"id": "3",
"name": "john"
}
]
messages.json
[
{
"from": 1,
"to": 2,
"message": "Please call me"
},
{
"from": 3,
"to": 2,
"message": "Please call me"
}
]
Showusers.js
import React, { useEffect, useState } from "react";
import axios from "axios";
import ShowSingle from "./ShowSingle";
import ShowRecentSingle from "./ShowRecentSingle";
function Showusers() {
const [users, setUsers] = useState();
const [loading, setLoading] = useState(true);
useEffect(() => {
axios
.get("http://localhost:3005/")
.then(function (response) {
setUsers(response.data);
console.log("users" + JSON.stringify(response.data));
setLoading(false);
})
.catch(function (error) {
console.log(error);
setLoading(false);
});
}, []);
return (
<div>
{!loading &&
users.map((user, id) => <ShowRecentSingle key={id} user={user} />)}
<input
type="text"
name="message"
id=""
className="message-input"
placeholder="type new message....."
/>
</div>
);
}
export default Showusers;
Solution with Map
You can maintain a map of active users who either send or receive messages and then filter out inactive users from the array of users with it.
const usersArray = [
{
id: 1,
name: "Rampal"
},
{
id: 2,
name: "Anisha"
},
{
id: 3,
name: "john"
}
];
const messagesArrary = [
{
from: 1,
to: 2,
message: "Please call me"
},
{
from: 3,
to: 2,
message: "Please call me"
}
];
const getActiveUserProfiles = (messages) => {
// map of users who sent or receive messages
const activeUsers = new Map();
messages.forEach(({ to, from }) => {
activeUsers.set(to, to);
activeUsers.set(from, from);
});
// filter out inactive users
return usersArray.filter(({ id }) => activeUsers.get(id));
};
const activeUserProfiles = getActiveUserProfiles(messagesArrary);
console.log(activeUserProfiles);
let users = [
{
"id": "1",
"name": "Rampal"
},
{
"id": "2",
"name": "Anisha"
},
{
"id": "3",
"name": "john"
}
];
let messages = [
{
"from": 1,
"to": 2,
"message": "Please call me"
},
{
"from": 3,
"to": 2,
"message": "Please call me"
}
];
let res = users.map(x => Object.assign(x, messages.find(y => y.from == x.id)));
for (let i = 0; i < res.length; i++) {
if(res[i].from === undefined) {
res.splice(i, 1);
}
}
console.log(res)

Calculating Averages in an Array and Displaying them on Page Load, Vue

I have an array called productsthat is structured like:
{
"_id": "150",
"name": "Milk",
"description": "Skimmed",
"price": "10",
"ratings": [
{
"email": "xyz#mail.com",
"rating": "5"
},
{
"email": "abc#mail.com",
"rating": "3"
},
{
"email": "def#mail.com",
"rating": "1"
},
]
},
{
"_id": "151",
...
...
...
I want to calculate the average rating of a product and display it on page load, using Vue.js.
My HTML page for products has a v-for = "(product, key) in products" Which I use to display all the products by name,desc etc.
Any help will be appreciated.
Thanks in advance.
You can try:
new Vue({
el: '#app',
data() {
return {
products: [
{
"_id": "150",
"name": "Milk",
"description": "Skimmed",
"price": "10",
"ratings": [
{
"email": "xyz#mail.com",
"rating": "5"
},
{
"email": "abc#mail.com",
"rating": "3"
},
{
"email": "def#mail.com",
"rating": "1"
},
]
}
]
}
},
mounted () {
// mapping each item of products to merge averageRating calculated
this.products = this.products.map(product => {
// ratings summation
const totalRatings = product.ratings.reduce((acc, { rating }) => acc += Number(rating), 0)
const averageRating = totalRatings/product.ratings.length
// returning the merge of the current product with averageRating
return {...product, averageRating}
})
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<div id="app">
<ul>
<li v-for = "(product, key) in products" :key="key">
name: {{ product.name }} ~ averageRating: {{ product.averageRating }}
</li>
</ul>
</div>
Try like below,
products = [
// The above array data ..
];
this.modifiedProducts = products.map(product => {
const average = product.ratings.reduce((total, next) => total + parseInt(next.rating), 0) / product.ratings.length;
return {
...product,
averageRating: average.toFixed(2)
}
});
.html
<ul>
<li v-for="product in modifiedProducts">
name: {{ product.name }} ~ AverageRating: {{ product.averageRating }}
</li>
</ul>
you can also use a simple javascript code where you can use a for loop to do that as well...
<script>
let ratingSum = 0
let myArray ={
_id: "150",
name: "Milk",
description: "Skimmed",
price: "10",
ratings: [
{
email: "xyz#mail.com",
rating: "5"
},
{
email: "abc#mail.com",
rating: "3"
},
{
email: "def#mail.com",
rating: "1"
},
]
}
// stringify your array as json array
var jsonArray = JSON.stringify(myArray)
// get the array length
var myArraylength = myArray.ratings.length
// use a for loop to loop through the array and sum all the ratings
for(i=0; i< myArray.ratings.length; i++){
ratingSum += parseInt(myArray.ratings[i].rating)
}
// after getting the sum of the rating divide it on the array length
myAverage = ratingSum / myArray.ratings.length
console.log(myAverage)
</script>

React changing array label names on map output

I have a React component which is access JSON data for populate a tree component. The tree is showing nodes and ports. Here is a sample from the JSON:
"outputs": {
"graph": {
"nodes":[ {
"name":"nlabme3400",
"ports":[ {
"name": "GigabitEthernet 0/2", "id": "5bd350c7-d15b-4f8b-be70-18eda2bfe41a"
}
,
{
"name": "FastEthernet 0/19", "id": "5bd350c7-762d-4462-984b-e6f0a9edb6c7"
}
,
{
"name": "FastEthernet 0/21", "id": "5bd350c7-2927-43db-ae43-119b12636de6"
}
],
"id":"5bd350bf-8515-4dc2-9b12-16b221505593"
}
I have all of this information coming in to my component via the following axios get call:
axios.get('StepThreeFinalData.json').then(response => {
const nodess = response.data.outputs.graph.nodes.map(({id, name,
...children}) => ({value: id, label: name, children: children.ports}));
The output is working perfectly. However, the challenge is that I need to change the "name" and "id" tags in the children array to "label" and "value", respectively, because otherwise the label will not show up in the tree component. Not sure how to do this. Please help!
const ports = [ {
"name": "GigabitEthernet 0/2", "id": "5bd350c7-d15b-4f8b-be70-18eda2bfe41a"
}
,
{
"name": "FastEthernet 0/19", "id": "5bd350c7-762d-4462-984b-e6f0a9edb6c7"
}
,
{
"name": "FastEthernet 0/21", "id": "5bd350c7-2927-43db-ae43-119b12636de6"
}
]
const update_ports = (ports) => ports.map(({ id, name }) => {
return { label: name, value: id }
})
console.log(update_ports(ports)) // The new ports with the new keys and values.
You can use the map function and return new array of objects with new keys and values in each item in the array.
axios.get('StepThreeFinalData.json').then(response => {
const nodess = response.data.outputs.graph.nodes.map(({id, name,
...children}) => ({value: id, label: name, children: update_ports(children.ports)}));
Notice i've called to update_ports in your axios success.
const test = {
"outputs": {
"graph": {
"nodes": [{
"name":"nlabme3400",
"ports": [
{
"name": "GigabitEthernet 0/2", "id": "5bd350c7-d15b-4f8b-be70-18eda2bfe41a"
},
{
"name": "FastEthernet 0/19", "id": "5bd350c7-762d-4462-984b-e6f0a9edb6c7"
},
{
"name": "FastEthernet 0/21", "id": "5bd350c7-2927-43db-ae43-119b12636de6"
}
],
"id":"5bd350bf-8515-4dc2-9b12-16b221505593"
}]
}
}
};
const test2 = test.outputs.graph.nodes.map(({name, ports, id}) => ({
name,
id,
ports: ports.map(({name, id}) => ({
label: name,
value: id
}))
}));
console.log(test2);
Read more about map, filter, reduce, that will save your life
axios.get('StepThreeFinalData.json').then(response => {
const nodess = response.data.outputs.graph.nodes.map(({id, name,
...children}) => ({value: id, label: name, children: update_ports(children.ports)}));

Combine es6 function every and sum and return boolean

I have a JSON response
{
"nextAction": [{
"userList": [{
"id": 8,
"email": "testemail#gmail.com",
"name": "John Doe"
}],
"buttonLabel": "Finalize Now"
},
{
"userList": [{
"id": 10,
"email": "newemail#gmail.com",
"name": "Test User"
}],
"buttonLabel": "Start Now"
}
]
}
The userList array sometimes contain null object.
I am working on a condition which satisfies the below 3 conditions.
The nextAction array should be non-empty.
The userList array shouldn't contain the null element.
The currentUser should be present in the userList array.
const data = [{
"userList": [{
"id": 8,
"email": "testemail#gmail.com",
"name": "John Doe"
}],
"buttonLabel": "Finalize Now"
},
{
"userList": [{
"id": 10,
"email": "newemail#gmail.com",
"name": "Test User"
}],
"buttonLabel": "Start Now"
}]
function checkForMyNextActions(myNextActions, currentUser) {
const checkUsername = obj => obj.email === currentUser;
return (myNextActions.forEach((myAction, index) => {
(myAction.userList.length &&
myAction.userList.every(userList =>
userList !== null) &&
myAction.userList.some(checkUsername)
)
}))
}
var result = checkForMyNextActions(data, "testemail#gmail.com")
console.log(result)
The expected result is true whereas I get undefined.
You could do this via some & find:
var obj = {
"nextAction": [{
"userList": [{
"id": 8,
"email": "testemail#gmail.com",
"name": "John Doe"
}],
"buttonLabel": "Finalize Now"
}]
}
const getUser = (usr) => obj.nextAction.some(({
userList
}) =>
userList ? (userList.every(userList => userList !== null) &&
userList.find(y => y.email === usr)) : false)
console.log(getUser("testemail#gmail.com")) // true
console.log(getUser("test#gmail.com")) // false
The nice thing about some method is that it returns boolean if one element matches the condition which in our case is the inner find for the email.
You can go little further and make the function accept a field to match on as well like this:
var obj = { "nextAction": [{ "userList": [{ "id": 8, "email": "testemail#gmail.com", "name": "John Doe" }], "buttonLabel": "Finalize Now" }] }
const getUser = (field="email", usr) => obj.nextAction.some(({userList}) =>
userList ? userList.find(y => y[field] === usr): false)
console.log(getUser("email", "testemail#gmail.com")) // true
console.log(getUser("name", "John Doe")) // true
checkForMyNextActions returns undefined because forEach returns undefined. Use map to call a function on each element in an array and return a new array with the return values of the functions. Also the inner function passed to forEach does not return anything.
You can simply use Array.reduce() for this:
const data = [{ "userList": [{ "id": 8, "email": "testemail#gmail.com", "name": "John Doe" }], "buttonLabel": "Finalize Now" }];
function checkForMyNextActions(myNextActions, currentUser) {
const checkUsername = obj => obj.email === currentUser;
return myNextActions.reduce((a,curr)=>{
let bool = curr.userList.length && curr.userList.every(userList =>userList !==null) && curr.userList.some(checkUsername);
return bool && a;
},true) != 0;
}
var result = checkForMyNextActions(data, "testemail#gmail.com")
console.log(result)

Categories