Reputation: 349
I have a small project with user cards.
I have a JSON file with data on users whose cards are generated.
My task is in the card to show the icons of those social networks that the user has. If the user does not have any of the social networks - do not show the icon of this social network in his profile.
Frankly, I do not understand how to do it.
The data in JSON come in this form (on the example of one user):
{
"id": 7,
"firstName": "Daniel",
"lastName": "Day-Lewis",
"profilePicture": "https://i2.wp.com/comicbookdebate.com/wp-content/uploads/2019/07/There20will20be20blood202-750x460.jpg?resize=750%2C460&ssl=1",
"contacts": [
"https://www.facebook.com/JasonStatham/",
"https://twitter.com/realjstatham",
"https://www.instagram.com/jasonstatham/?hl=ru"
]
}
JS index file (add so that it is clear how I work with a layout in this project):
'use strict';
const cardsContainer = document.querySelector('#root');
async function loadCards(url) {
try {
const response = await fetch(url);
const data = await response.json();
const cards = data.map((data) => generateUserCard(data));
cardsContainer.append(...cards);
} catch(e) {
throw new Error(e);
}
}
loadCards('./assets/js/data.json');
function generateUserCard(userObj) {
const fullName =
`${userObj.firstName} ${userObj.lastName}`.trim() ||
CARD_CONSTANTS.userName;
const imgWrapper = createUserCardImageWrapper(userObj, fullName);
const cardName = createElement('h2', {classNames: ['cardName']}, fullName);
const cardDescription = createElement('p', {classNames: ['cardDescription']}, userObj.description || CARD_CONSTANTS.cardDescription);
const cardArticle = createElement('article', {classNames: ['cardContainer']}, imgWrapper, cardName, cardDescription);
const card = createElement('li', {classNames: ['userCardWrapper']}, cardArticle);
return card;
}
function createUserCardImageWrapper(userObj, fullName) {
const userImgElem = createElement('img', {
classNames: ['cardImg'],
attributes: {
src: userObj.profilePicture,
alt: fullName,
'data-id': userObj.id,
},
listeners: {
error: errorHandler,
load: loadHandler,
},
});
const initialsElem = createElement(
'div',
{ classNames: ['initials'] },
getInitials(fullName)
);
const imgWrapperElem = createElement(
'div',
{
classNames: ['cardImgWrapper'],
attributes: { id: `imgWrapper${userObj.id}` },
},
initialsElem
);
return imgWrapperElem;
}
function errorHandler({ target }) {
target.remove();
}
function loadHandler({
target,
target: {
dataset: { id },
},
}) {
document.getElementById(`imgWrapper${id}`).append(target);
}
I associate social networks with icons in this way (on the example of Twitter):
const SUPPORTED_SOCIAL_NETWORKS = new Map([
[
"twitter.com",
{
src: "https://w7.pngwing.com/pngs/872/50/png-transparent-computer-icons-social-media-logo-twitter-social-media-blue-logo-social-media-thumbnail.png",
alt: "twitter link for",
},
],
["www.facebook.com"],
]);
Upvotes: 0
Views: 332
Reputation: 4603
This is actually quite straightforward, see the comments in the code
// Get the network hosts for of a user and optionally filter them
let getNetworkHosts = (userId, filter) => {
if (match = users.filter( user => userId === user.id )) {
contacts = match[0].contacts.map( url => (new URL(url)).hostname)
if (filter) contacts = contacts.filter(filter)
return contacts
}
}
// A filter that can be applied to a list
let supportedNetworkFilter = elem => SUPPORTED_SOCIAL_NETWORKS[elem]
// Create an image tag
let createImage = (url) => {
let img = document.createElement("img")
img.src = url
return img
}
users =
[ { "id": 7
, "firstName": "Daniel"
, "lastName": "Day-Lewis"
, "profilePicture": "https://i2.wp.com/comicbookdebate.com/wp-content/uploads/2019/07/There20will20be20blood202-750x460.jpg?resize=750%2C460&ssl=1"
, "contacts":
[ "https://www.facebook.com/JasonStatham/"
, "https://twitter.com/realjstatham"
, "https://www.instagram.com/jasonstatham/?hl=ru"
]
}
]
const SUPPORTED_SOCIAL_NETWORKS =
{ "twitter.com":
{ src: "https://w7.pngwing.com/pngs/872/50/png-transparent-computer-icons-social-media-logo-twitter-social-media-blue-logo-social-media-thumbnail.png"
, alt: "twitter link for"
}
, "www.facebook.com": {} // Oops, facebook has no face
}
// Add some images to a div
let div = document.getElementById('images')
for (network of getNetworkHosts(7, supportedNetworkFilter)) {
div.appendChild(createImage(SUPPORTED_SOCIAL_NETWORKS[network].src))
}
<div id="images"></div>
Upvotes: 1