I'm trying to build the footer of Netflix dynamically with Reactjs and styled components but i couldn't figure it out how to do it. Any help would be apprciated :)
I created the links in a links.json file
[
{
"id": 1,
"link": "FAQ"
},
{
"id": 2,
"link": "Investor Relations"
},
{
"id": 3,
"link": "Privacy"
},
{
"id": 4,
"link": "Speed Test"
},
{
"id": 5,
"link": "Help Center"
},
{
"id": 6,
"link": "Jobs"
},
{
"id": 7,
"link": "Cookie Preferences"
},
{
"id": 8,
"link": "Legal Notices"
},
{
"id": 9,
"link": "Account"
},
{
"id": 10,
"link": "Ways to Watch"
},
{
"id": 11,
"link": "Coorporate Information"
},
{
"id": 12,
"link": "Only on Netflix"
},
{
"id": 13,
"link": "Media Center"
},
{
"id": 14,
"link": "Terms of use"
},
{
"id": 15,
"link": "Contact US"
}
]
Then in my footer component I tried to perform the filter and map functions but i can't implement the code: it only display 4 items per column inside a ul tag :(((
import React from 'react'
import linksData from '../fixtures/links'
import './Footer.css'
function Footer() {
return (
// <div>
// {linksData
// .filter()
// .map((item, index)=>(
// <li key={index}>{item.link}</li>
// )
// )}
// </div>
<div className="site-footer-wrapper">
<div className="site-footer">
<p className="footer-top">
<a className='footer-top-a' href> Questions? Contact US</a>
</p>
<ul className='footer-links'>
<li className='footer-link-item'>FAQ</li>
<li className='footer-link-item'>Investor Relations</li>
<li className='footer-link-item'>Privacy</li>
<li className='footer-link-item'>Speed Test</li>
</ul>
<ul className='footer-links'>
<li className='footer-link-item'>FAQ</li>
<li className='footer-link-item'>Investor Relations</li>
<li className='footer-link-item'>Privacy</li>
<li className='footer-link-item'>Speed Test</li>
</ul>
<ul className='footer-links'>
<li className='footer-link-item'>FAQ</li>
<li className='footer-link-item'>Investor Relations</li>
<li className='footer-link-item'>Privacy</li>
<li className='footer-link-item'>Speed Test</li>
</ul>
</div>
</div>
)
}
export default Footer
I would appreciate any help of how to do this, either with the map() function or with CSS rules.
Thank you
One thing that could be beneficial is separating the concerns. Create a separate component that will handle one column at a time.
In my case, I created a Column component that returns a 'ul' JSX tag and display 'li' JSX tags based on linksToDisplay array received as props.
const Column = ({ linksToDisplay, key }) => (
<ul key={key} className='px-4'>
{linksToDisplay.map((item) => (
<li key={item.id}>{item.link}</li>
))}
</ul>
);
Then, I use my Column component inside my Footer component to display the columns based on a set criteria.
const Footer = () => {
return (
<div className='container mx-auto flex px-2 lg:px-5 py-24 h-screen
items-center justify-center flex-row'>
{links.map((link, index) => {
// So you get a new column after 4 items have been displayed
if (index % 4 === 0) {
// Array.slice to get the next 4 links in the array
const nextFourLinks = links.slice(index, index + 4);
return <Column key={link.id} linksToDisplay={nextFourLinks}
/>;
}
})}
</div>
);
};
After that, apply some styling to your elements and in my case I am using tailwindCSS and you should have your columns displaying the links.
Output:
For reference:
Array.prototype.slice()
Related
Given the following JSON response, how would I group them according to team first, then by year, using javascript and/or jsx to map the response? I'm using Astro.
{
"data": [
{
"id": 1,
"team_name": "Team One",
"players": [
{
"player_name": "Mickey Mantle",
"players_year": {
"year": 2024
}
},
{
"player_name": "Larry Smalls",
"players_year": {
"year": 2022
}
},
{
"player_name": "Ron Davis",
"players_year": {
"year": 2024
}
}
]
},
{
"id": 2,
"team_name": "Team Two",
"players": [
{
"player_name": "Jim Abbot",
"players_year": {
"year": 2022
}
}
]
}
]
}
End Result – The HTML output should match this:
<div class="group">
<h2>Team One</h2>
<h3>2022</h3>
<ul>
<li>Larry Smalls</li>
</ul>
<h3>2024</h3>
<ul>
<li>Mickey Mantle</li>
<li>Ron Davis</li>
</ul>
</div>
<div class="group">
<h2>Team Two</h2>
<h3>2022</h3>
<ul>
<li>Jim Abbot</li>
</ul>
</div>
Currently, here is my file which works, but without the grouping as seen directly above. What additional javascript is needed in Astro's frontmatter and markup required in the body of the page?
teams.astro
---
const directus = await getDirectusClient()
const response = await directus.items("teams").readByQuery({
fields: [
"id",
"team_name",
"players.player_name",
"players.players_year.year",
],
})
const formattedResponse = response.data.map((team) => {
return {
...team,
yearsArr: team.players.map(player => player.players_year.year)
}
})
const [...teams] = formattedResponse
---
<h1>Teams Page</h1>
{
teams.map((team) => {
return (
<div class='group'>
<h2>{team.team_name}</h2>
<ul>
{team.players.map((player) => (
<li>
{player.player_name} ({player.players_year.year})
</li>
))}
</ul>
</div>
)
})
}
This have been asked many times before. But not exactly like this.
Update: added the html markup (for Astro).
var obj = {data:[{id:1,team_name:"Team One",players:[{player_name:"Mickey Mantle",players_year:{year:2024}},{player_name:"Larry Smalls",players_year:{year:2022}},{player_name:"Ron Davis",players_year:{year:2024}}]},{id:2,team_name:"Team Two",players:[{player_name:"Jim Abbot",players_year:{year:2022}}]}]};
var result = {};
obj.data.forEach(function(item) {
result[item.team_name] = result[item.team_name] || {}
item.players.forEach(function(player) {
result[item.team_name][player.players_year.year] = result[item.team_name][player.players_year.year] || [];
result[item.team_name][player.players_year.year].push(player.player_name);
})
})
console.log(result)
.as-console-wrapper {
max-height: 100% !important
}
<h1>Teams Page</h1>
{Object.entries(result).map(([team_name, team]) => { return (
<div class='group'>
<h2>{team_name}</h2>
{Object.entries(team).map(([year, players]) => (
<h3>{year}</h3>
<ul>
{players.map(player_name) => (
<li>
{player_name}
</li>
)}
</ul>
))}
</div>
) }) }
Here's what I want to achieve. I've 2 arrays, one for artists and one for releases. I am currently matching "ArtistID" to each to display "Releases by this artists" on my SingleArtist page. However I want to take it a step further and add another identifier if the release features them. Example : release A has artist A, but a remixer B. Is there a way to do it within by doing more filtering on the arrays(s)? Not sure how to go about it. Thanks.
example from releases.json
{
"id": 9,
"artistID": "SU",
"featuredartist": "ES, FG",
"imageURL": "../images/releases/dulcie.jpg",
"title": "Dulcie Caught a Cricket",
"description": "Released 2020",
"artist": "Sumsuch",
"buy": "https://www.beatport.com/release/we-choose/1916121",
"stream": "https://open.spotify.com/album/4cutoknbgciTGGpAYSZXfK?si=gsNvR6ytTN6KdrPORfSLOg"
},
example from artists.json (the second object is a remixer 'id:0' who is featured on 'id:3' and would like that to display under the "ES" releases
{
"id": 3,
"artistID": "SU",
"imageURL": "./images/sumsuch.jpg",
"singleimageURL": "../images/artists/sumsuch.jpg",
"name": "SUMSUCH",
"bio": "Will Sumsuch has been a musician, producer and DJ",
"soundcloud": "sumsuch"
},
{
"id": 0,
"artistID": "ES",
"imageURL": "./images/artists/ericblue.jpg",
"singleimageURL": "../images/artists/ericblue.jpg",
"name": "ERIC SHANS",
"bio": "A producer and DJ residing in Brooklyn, NY,
},
code for singleartist.js (abbreviated)
function SingleArtist() {
const { id } = useParams() //finds single artist from array & matches ID
const artist = artists.find((a) => a.id === +id)
//finds ArtistID from Artists then matches any item that has the same value from the Releases array
const releaseList = releases.filter((b) => b.artistID === artist.artistID)
const { singleimageURL, name, soundcloud, bio } = artist
return (
<Wrapper>
<div className="artist-container">
<div className='item'>
<div className='image'>
<img className='artist' src={singleimageURL} alt={name} />
</div>
<div className="description">
<p className='name'>
{name}
</p>
<p className='bio'>
{bio}
</p>
</div>
<a href={'https://soundcloud.com/' + soundcloud} target="_blank" rel="noreferrer">
Listen to {name}'s Soundcloud
</a>
</div>
</div>
<span>
<Link className='link-back' to="/artists"> Back To Artists</Link>
</span>
<div className="matches">
<h4> Releases by {name} </h4>
{releaseList.map(release => {
const { imageURL, name, id, buy } = release;
return (
<div className="item" key={id}>
<a href={buy} target="_blank" rel="noreferrer">
<img className="image" src={imageURL} alt={name} />
</a>
</div>
)
})}
</div>
</Wrapper>
)
}
The way I understand your question, you simply want to find a list of releases that an artist is featured in on the single artist page. This line should do the trick:
let releases = [{
"id": 9,
"artistID": "SU",
"featuredartist": "ES, FG",
},{
"id": 3,
"artistID": "ED",
"featuredartist": "SU, FG",
}]
const featuredList = releases.filter(release => release.featuredartist.split(", ").includes("SU"));
console.log(featuredList);
You can insert this directly below the line where you set releaseList. It is basically the same idea. This line filters the releases again, and then splits the featuredartists string into an array of strings. Then, if the array includes the artist's id, you return it.
What I Want to Do:
I want to render a list of elements using .map, then sort by most recent on top. I've tried adding .sort and .filter before rendering the element, but it doesn't seem to be working. I've done some quick Google searches, but came across posts which don't seem relevant to what i'm trying to do. (or it's just me).
I want to sort by date, with the most recent on top.
Render Component:
import React from "react";
import TransactionEntry from "./TransactionEntry";
function Transactions({ transactionList }) {
return (
<div className="flex flex-col items-start justify-start w-full h-[520px] overflow-auto gap-3 no-scrollbar">
{transactionList.map((transaction) => {
return (
<TransactionEntry
id={transaction.id}
retailer={transaction.retailer}
category={transaction.category}
price={transaction.price}
dateAdded={transaction.dateAdded}
/>
);
})}
</div>
);
}
export default Transactions;
Data Structure:
[
{
"id": "ts001",
"category": "Category",
"retailer": "Retailer",
"price": 1.99,
"dateAdded": "04/02/01"
},
{
"id": "ts002",
"category": "Category",
"retailer": "Retailer",
"price": 13.99,
"dateAdded": "04/02/04"
},
{
"id": "ts003",
"category": "Category",
"retailer": "Retailer",
"price": 119.99,
"dateAdded": "04/02/09"
}
]
You can sort before mapping in this way
{transactionList.sort((a, b) => new Date(a.dateAdded) - new Date(b.dateAdded)).map((transaction) => {
return (
<TransactionEntry
id={transaction.id}
retailer={transaction.retailer}
category={transaction.category}
price={transaction.price}
dateAdded={transaction.dateAdded}
/>
);
})}
I am using Vue and I have the array of objects and I need to use it to create a menu using that.
The array list looks like the following:
[{
"name": "Menu 1",
"url": "/link/menu-1",
"sub-menus": []
},
{
"name": "Menu 2",
"url": "/link/menu-2",
"sub-menus": [
{
"name": "Menu 2-1",
"url": "/link/menu-2-1",
"sub-menus": []
},
{
"name": "Menu 2-2",
"url": "/link/menu-2-2",
"sub-menus": []
}
]
},
{
"name": "Menu 3",
"url": "/link/menu-3",
"sub-menus": [
{
"name": "Menu 3-1",
"url": "/link/menu-2-1",
"sub-menus": [
{
"name": "Menu 3-1-1",
"url": "/link/menu-3-1-1",
"sub-menus": []
}
]
},
{
"name": "Menu 3-2",
"url": "/link/menu-2-2",
"sub-menus": []
}
]
}]
Since there are multiple sub-menu levels, I have no idea how to generate the menu dynamically.
The level of sub-menu is not fixed. It can be no sub-menu or more than 2 or 3 levels.
I want the output to be something like the following.
<ul>
<li>
Menu 1
</li>
<li>
Menu 2
<ul>
<li>
Menu 2-1
</li>
<li>
Menu 2-2
</li>
</ul>
</li>
</ul>
Since i am new to Vue, i have no idea how this can be achieved. Thanks in advance.
I think you can do it with two components.
One that will build a menu for itself and it's sub ones :
var Menu = ({
name:"Menu",
template: `
<li>
<a :href="url">{{name}}</a>
<ul v-if="subMenus.length > 0">
<Menu
v-for="menu in subMenus"
:name="menu.name"
:url="menu.url"
:subMenus="menu['sub-menus']">
</Menu>
</ul>
</li>`,
props: {
name: {type:String, required:true},
url: {type:String, required:true},
subMenus: {type:Array, required:true}
}
})
And another one to insantiate everything, that will iterate over your menu list (that you will pass as a prop) :
var FullMenu = ({
components: {Menu},
name:"FullMenu",
template: `
<div>
<ul>
<Menu
v-for="menu in menus"
:name="menu.name"
:url="menu.url"
:subMenus="menu['sub-menus']">
</Menu>
</ul>
</div>
`,
props: {
menus: {type:Array, required:true}
}
})
Just use it like this:
<div>
<full-menu :menus="yourMenuListAsDataOrProps"></full-menu>
</div>`
Here is a running example on Observable : https://observablehq.com/d/802261a535698d88#FullMenu
i fixed this issue like below way:
use this in template section =>
<span v-html="hasChild(chart)"></span>
and hasChild method =>
hasChild(chart){
var html = ''
if(chart.childs.length>0){
html = html+'<ul>'
chart.childs.map(child=>{
html = html+'<li>'
html = html+'<a>'+child.title+'</a>'
if(child.childs.length>0){
html = html+this.hasChild(child)
}
html = html+'</li>'
})
html = html+'</ul>'
return html
}
}
and work fine for me.
I'm having a dynamic JSON, which contains the list of name, it also contains the children names as a subset. How can I show it in the HTML UI using angularJS ng-repeat
The Sample Dynamic JSON is
$scope.family = [
{
"name":"Siva",
"child":[
{
"name":"Suriya"
},
{
"name":"Karthick"
}
]
},
{
"name":"Kumar",
"child":[
{
"name":"Rajini"
},
{
"name":"Kamal"
},
{
"name":"Ajith"
}
]
},
{
"name":"Samer"
},
{
"name":"Mahesh"
}
];
<div ng-repeat="members in family">
<!-- How to Show it in the UI -->
</div>
Note: The JSON is generated based on Request. The Child array is
Optional and it may contain the length 'n'
You can better your answer by adding an ng-if directive, as the child is optional. Of course, it won't make any impact to you app, but it is a good way to code.
Plus, instead of adding ng-repeat on ul, it should be in li. It makes no sense in looping the ul for a single list.
Please refer the sample here.
HTML:
<div ng-app="app" ng-controller="test">
<ul ng-repeat="member in family">
<li>
{{member.name}}
<span ng-if="member.child.length > 0">
<ul>
<li ng-repeat="c in member.child">{{c.name}}</li>
</ul>
</span>
</li>
</ul>
</div>
JS:
var app = angular.module('app', []);
app.controller('test', function ($scope) {
$scope.family = [
{
"name": "Siva",
"child": [
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer"
},
{
"name": "Mahesh"
}
];
});
The Corrected answer
<ul ng-repeat="member in family">
<li>{{member.name}}
<ul>
<li ng-bind="c.name" ng-repeat="c in member.child"></li>
</ul>
</li>
</ul>