Maping inside a map - Vanilla Javascript - javascript

Coding noob here :)
I'm working on a project where I have prepared an array that I'm mapping over and printing. Inside the array I have another array, called "lang", that I can't reach from the map. I want to print each item in that array into an <li>, as the code is now all the items are printed as one <li> , which I don't want. I have tried maping inside the map in various ways but not gotten it to work.
Is the right way to do a map inside the map? In that case, how is it done?
Is there another way to do this?
Please see part of the array and the map function I have created down below. projectContainer, which I'm adding the innerHTML to, is a div inside the index.html file.
},
{
img: "./pictures/guess-who.png",
projectTitle: 'GUESS WHO?',
projectDescription: 'Recreation of the game "Guess who?" built with HTML, CSS and JavaScript.',
lang: [
'HTML', 'CSS', 'JavaScript'
],
url: '',
className: '',
id: 6
}
]
}
const printProjects = () => {
projectArray.projects.map((project) => {
projectContainer.innerHTML += `
<div class="project-container ${project.id}">
<img src=${project.img} alt="picture of guess who game"></img>
<h4>${project.projectTitle}</h4>
<p>${project.projectDescription}</p>
<ul>
<li>${project.lang} </li>
</ul
</div>
`
})
}
printProjects()

You can do something like this and use map(...).join('')
<ul>
${project.lang.map(el => `
<li>${el}</li>
`).join('')}
</ul>

Related

Data bound v-if dynamic condition

I was wondering if it's possible to have a data binded v-if directive, I have an array of objects representing nav links or buttons (for login , logout ...) each of this objects has a v-if property where I define the v-if condition as a string.
From my laravel backend:
$globals['socialLinks'] =
[
[ 'title' => 'facebook', 'v-if' => '$app.auth', 'icon' => 'fab fa-facebook-f', 'url' => config('app.facebook'), 'image' => '/img/social/facebook-alt-white.svg' ],
];
In my template (I transform this into json and pass it to my vue component template):
<div class="LAYOUTfooter9_row_container">
<a class="LAYOUTfooter9_social_image_container" :href="social.url" v-for="(social,index) in $app.globals.socialLinks" v-if="[social.v-if]" :key="index+'S'">
<img class="LAYOUTfooter9_social_image" :src="social.image">
</a>
</div>
Execute JavaScript code stored as a string can be dangerous. Think twice if you really need it...
<a class="LAYOUTfooter9_social_image_container" :href="social.url" v-for="(social,index) in $app.globals.socialLinks" v-if="evaluateCondition(social.v-if)" :key="index+'S'">
methods: {
evaluateCondition(condition) {
return eval(condition)
}
}
Your conditions have to be an expression and will be executing in the context of Vue instance so instead of $app.auth you need to use this.$app.auth

How to show all properties of an object in HTML in React

{
title: "My Title",
entryID: 1,
url: "#",
author: "William Pears, Andrew Cutcher",
comment_count: 2
}
I got this object and I am trying to figure out how to display this in my React component.
I want to display like a blog entry where when clicking on title I could hopen the link (url) and show author also on the blog entry..
Please help!!
Map overs the keys of object
{Object.keys(yourObject).map(function(key) { return <div>Key: {key}, Value: {yourObject[key]}</div>; })}
Two things here:
where will you store the data?
is it in state?
then use this.state.{propertyName}
#dotnetdev4president explained how to access this.state.property, except, you should wrap the reference in curly braces
is it in a constant?
then check my example below with JavaScript’s .map method
for rendering/displaying the data to React Components
you might want to check this for blog-like entries: https://reactstrap.github.io/components/card/
Loop through your object, with the above mentioned .map like so:
const yourExampleDataConstant = {
title: "My Title",
entryID: 1,
url: "#",
author: "William Pears, Andrew Cutcher",
comment_count: 2
};
return <div>
{yourExampleDataConstant.map(element => (
return <ul key={element.entryID} >
<a href={element.url}><li>{element.title}</li></a>
<li>{element.author}</li>
<li>{element.comment_count}</li>
</ul>
))}
</div>;
}
However, context of your code would be useful!
Hope this helps!
PS.
Looks while I was writing an answer, #nikhilkarkra already replied with what I had in mind :)
If you saved your data into the state with this.setState({your_object}) you can output easyly in jsx:
<p>this.state.title</p>
<p>this.state.author</p>
And so on...

Vue Router Setup work when visited directly via URL

I'm looking for advice on how to go about this routing scenario:
I have the following HTML that loops category and items in the category. The <router-view> is inside the category so that when an item is clicked it will open only in the category that related to that item.
<ul>
<li v-for="cat in categories">
<ul>
<li v-for="business in filteredByCat">{{business.name}}</li>
</ul>
<router-view v-if="..."></router-view>
</li>
</ul>
My routes are as follows:
{
path: '/businesses',
name: 'Directory',
component: Directory,
children: [{
path: ':listing',
name: 'Listing',
component: Listing
}]
}
Visualization:
How do I get the data of the item clicked to pass to the router-view? I assume I'd use props but that wouldn't work if the user visited details directly by URL?
I tried getting the item like so:
methods: {
finalItem ($route) {
var match = this.businesses.filter((business) => {
return business.link === $route.params.listing
})
return match[0]
}
}
This doesn't work, even if it did, this feels wrong. Is there a way to pass the data in a way that would preserve even when visited directly? This is my primary concern. (I understand the repeated <router-view> is bad code but am not sure how to get around doing that with my layout. Open to suggestions on that too though.)
The way you're using router-view, you might as well just drop a component in. As far as using multiple router-views goes, it's very common, so idk what #varbrad is talking about there. Child routes are fine.
The not-so-common part is using multiple router-view's in one component. The UI you're aiming for is nearly identical to Netflix. If you check out what they're doing, you'll see that they pass a movie ID (business id/shortname) as "jbv" and a row number (category name) as "jbr" in the route query.
Let's mimic this in your component:
I'm not sure what filteredByCat looks like, but the way you have it set up, it would list the same businesses for every category. Try something like this:
computed:{
businessesByCategory(){
let dictionary = {};
this.businesses.forEach(business=>{
business.categories.forEach(category=>{ // assuming each business has an array of categories
dictionary[category] = dictionary[category] || [];
dictionary[category].push(business)
})
})
return dictionary;
}
},
data(){
return {
activeBusiness:null
}
},
methods:{
setActiveBusiness(business){
this.activeBusiness = business;
},
setUrlQuery(listing, category){
this.$route.query.listing = listing;
this.$route.query.category = category;
},
openListing(business, category){
this.setActiveBusiness(business);
this.setUrlQuery(business.link, category);
}
}
-
<ul>
<li v-for="cat in categories">
<ul>
<li
v-for="business in businessesByCategory[cat]"
#click="openListing(business, cat)"
>
{{business.name}}
</li>
</ul>
<Listing :business="activeBusiness" v-if="$route.query.category == cat"></Listing>
</li>
</ul>

AngularJS ui-sref external (absolute) link

I wrote a little angular app. I've got an array of menu items which I print in my template:
<nav id="menu">
<ul>
<li ng-repeat="i in menuItems"
ui-sref="{{ i | removeSpacesThenLowercase }}"
ui-sref-active="active">{{ i }}</li>
</ul>
</nav>
And in my app.js I declared my states using ui-router like:
.state('camera', {
url: '/selection',
templateUrl: '/views/selection.html',
uiShade: 'light back',
back: 'intro'
})
Internal URLs work just fine, but what if I want to do this?
.state('facebook', {
url: 'https://www.facebook.com/'
})
This obviously doesn't work. What would be the best approach to have some external (absolute) links in my template without having two separate arrays?
Ui-sref refers to a state. Your views are states. Externals sites aren't states, it's just some outside links.
I suggest you to refactor your menu generator to handle different type of menu entries :
state based link (link generated through ui-sref)
standard link (link generated through href, for external links, emails, etc)
Then you just have to populate menuItems with an array of different objects
I fixed this in my application using ng-if.
Example menu items:
$scope.navItems = [{
id: 1,
title: 'Internal Link',
href: null,
sref: 'internal-state'
},
{
id: 2,
title: 'External Link',
href: 'https:/google.co.uk',
sref: null
}];
Then in the HTML I set the ng-repeat on the <li> but include an <a> for href and one for sref, each with an ng-if.
<li ng-repeat="item in navItems">
<a ng-if="item.sref" ui-sref="{{item.sref}}">{{ item.title }}</a>
<a ng-if="item.href" href="{{item.href}}">{{ item.title }}</a>
</li>
I fixed this by creating a second array for the external links and an ng-click function.
$scope.elink = function(element) {
if (confirm("You're leaving the app, are you sure?")) {
window.location = element;
}
};

Handlebars #each fails with one item

I have a handlebars template that uses each statements, one nested inside the other.
It works just fine, until the inner each comes across an item in the data set that only has one item, in which case it doesn't output anything.
Here's my template:
<div class="container">
{{#each stories.story}}
<div class="story">
<h1 class="mask">
<span>
{{copy.heading}}
</span>
</h1>
<ul class="story-copy">
{{#each copy.body.text}}
<li class="mask">
<span>{{this}}</span>
</li>
{{/each}}
</ul>
</div>
{{/each}}
</div>
The interesting thing, as I said, is that when the ul is being output when copy.body.text has more than one text node, it works. If there is only ONE, it comes out empty.
There's gotta be something I'm missing. Can anyone help?
couldn't reproduce your bug.
can you post your data?
this one works for me: http://jsfiddle.net/Schniz/7v0qawbd/
var data = {
stories: {
story: [{
copy: {
heading: "hello",
body: {
text: [
"Hey"
]
}
}
}]
}
};
yet, even though I don't really know how your data looks, I think looks like your template should be kinda different: http://jsfiddle.net/Schniz/Ly8uh2u1/ for using with data that looks like:
var data = {
stories: [{
copy: {
heading: "hello",
body: [
"Hey"
]
}
}]
};

Categories

Resources