how can I iterate through this json file? - json

I want to do my cv in react.
I have a json file that contains all my experience, education and more however I come across a problem when I output the data
{
"experience":[
{
"Title":"Somewhere",
"Date":"2015 - 2015",
"Description":
[
"Participate in the full development lifecycle, following a SCRUM methodology applied to core product",
"Participate in the full development lifecycle, following a SCRUM methodology applied to core product",
"Participate in the full development lifecycle, following a SCRUM methodology applied to core product"
]
},
{
"Title":"Somewhere",
"Date":"2015 - 2015",
"Description":
[
"Participate in the full development lifecycle, following a SCRUM methodology applied to core product",
"Participate in the full development lifecycle, following a SCRUM methodology applied to core product",
"Participate in the full development lifecycle, following a SCRUM methodology applied to core product"
]
}
]
}
I am calling it in experience.js
const Experience = (props) => (
<div className="container">
<p className="subtitle">WORK EXPERIENCE</p>
<hr className="subtitles"/>
<ul className="left-box">
{props.data.map((info,i) =>
<li key={i} className="top">
<div className="year">
<h4>{info.Date}</h4>
<span> {info.Title}</span>
</div>
<div className="box-content" >
<h4 className="sameHeightTitle">Front End Developer</h4>
<ul className="left-box-content">
<li className="sec-layer">
{info.Description}
</li>
</ul>
</div>
</li>
)}
</ul>
</div>
);
the problem is instead of having the description in bullet form I have it all on the same bullet. Basically every string that starts with Participate in my json file should be next to a new bullet.The following is screenshot of the output:
EDIT: Answer
const Experience = (props) => (
<div className="container">
<p className="subtitle">WORK EXPERIENCE</p>
<hr className="subtitles"/>
<ul className="left-box">
{props.data.map((info,i) =>
<li key={i} className="top">
<div className="year">
<span className="sub-sub-title"> {info.Title}</span>
<h4>{info.Date}</h4>
</div>
<div className="box-content" >
<h4 className="sameHeightTitle">Front End Developer</h4>
<ul className="left-box-content">
{info.Description.map((newDesc, o)=>
<li>
{newDesc}
</li>
)}
</ul>
</div>
</li>
)}
</ul>
</div>
);

Your Description is an array. You need to iterate over it. What js library are you using? You'll need to find out how you iterate over a list in that language.
This isn't the syntax for the foreach loop, but you'll get the idea.
foreach(var description in info.Description){
<li className="sec-layer">
{description}
</li>
}

Related

Extracting Multiple Child Elements from a Parent using Cheerio

I'm trying to use Cheerio to scrape data and ultimately convert the resultant HTML to Markdown.
While not core to this question, to convert to Markdown, all I need is some valid HTML. Specifically, for this case, a div with one or more <ul> tags.
I mention this so it's clear that I'm not using the resultant HTML to directly render, but I need it in a form that I can use to convert to Markdown.
Using the simplified example below and given a known class name of "things", there are two <ul> tags in the parent div.
Note that the ul tags do not have a class or id in the code I'm scraping.
<div class="things"> // <= want
<h5 class="heading">Things</h5> // <= don't want
<ul> // <= want with children
<li class="sub-heading">Fruits</li>
<li class="fruit-item">Apple</li>
<li class="fruit-item">Pear</li>
</ul>
<ul> // <= want with children
<li class="sub-heading">Veg</li>
<li class="veg-item">Carrot</li>
<li class="veg-item">Spinach</li>
</ul>
</div>
I want every ul with their list items in a surrounding div.
The following results HTML w/o a surrounding div and with stuff I don't want (e.g. <h5 class="heading">Things</h5>):
const stuffIWant = $(".things").html();
The following results HTML w/o a surrounding div, only the contents on one of the <ul> tags, not the ul itself:
const stuffIWant = $(".things ul").html();
I know that this is because .html() returns the first element, so I'm just getting the list items from the first ul.
This my problem and is where I'm confusing myself.
I've also tried various forms of filter, map, and each, but I can't, for the life of me, get multiple <ul> tags returned in an enclosing div.
I'm thinking maybe I need iterate through the "things" div, using each or map and append the elements I want to a new div (somehow?), but that seems more complicated than it should be, so I'm asking here.
Any advice toward helping me wrap my head around this would be much appreciated.
Thanks.
While this post wasn't clarified completely, it seems there are two ways to interpret it. One possibility is that you want all of the <li>s for each of your <ul>s in a series of arrays:
const $ = cheerio.load(html);
const result = [...$(".things ul")].map(e =>
[...$(e).find("li")].map(e => $(e).text())
);
console.log(result);
Which gives
[
[ 'Fruits', 'Apple', 'Pear' ],
[ 'Veg', 'Carrot', 'Spinach' ],
]
Now, if the <div class="things"> wrapper is repeated and you want to distinguish each of these groups, you can modify the above code as follows:
const cheerio = require("cheerio"); // 1.0.0-rc.12
const html = `
<div class="things">
<h5 class="heading">Things</h5>
<ul>
<li class="sub-heading">Fruits</li>
<li class="fruit-item">Apple</li>
<li class="fruit-item">Pear</li>
</ul>
<ul>
<li class="sub-heading">Veg</li>
<li class="veg-item">Carrot</li>
<li class="veg-item">Spinach</li>
</ul>
</div>
<div class="things">
<h5 class="heading">Things 2</h5>
<ul>
<li class="sub-heading">Foo</li>
<li class="fruit-item">Bar</li>
<li class="fruit-item">Baz</li>
</ul>
</div>
`;
const $ = cheerio.load(html);
const result = [...$(".things")].map(e =>
[...$(e).find("ul")].map(e =>
[...$(e).find("li")].map(e => $(e).text())
)
);
console.log(JSON.stringify(result, null, 2));
This gives:
[
[
[
"Fruits",
"Apple",
"Pear"
],
[
"Veg",
"Carrot",
"Spinach"
]
],
[
[
"Foo",
"Bar",
"Baz"
]
]
]
In other words, there's an extra layer:
- .things
- ul
- li
as opposed to the top code, which flattens .things:
- .things ul
- li

How to format JSON data fetch from API

Am getting data from API and trying to display it in my angular application I can able to fetch and display the data but it's not in a good format.
{
"countryCode": "BS",
"countryName": "BAHAMAS",
"publishedDate": "2020-03-30T00:00:00.000Z",
"alertMessage": "\nAll international flights to Uganda are suspended until 24 April 2020.|\n- This does not apply to:|\n1. Aircraft in a state of emergency.||\n2. Operations related to humanitarian aid, medical and relief flights.||\n3. Technical landings where passengers do not disembark.||\n4. Any other flight that may be so approved by the appropriate authority.||\n"
},
{
"countryCode": "FJ",
"countryName": "FIJI",
"publishedDate": "2020-03-30T00:00:00.000Z",
"alertMessage": "\n1. Passengers and airline crew are not allowed to enter Fiji.|\n- This does not apply to nationals of Fiji.||\n2. Nationals of Fiji must go into quarantine for a period of 14 days.||\n"
}
JSON data which I get from API.
The output which is expecting is
but the output which am getting is
my code as follows
<div class="card" style="width: 69rem;" *ngFor="let alert of jsonValue">
<div class="card-body" #{{alert.countryName}}>
<div class="container">
<div class="row">
<div class="col">
<span> <p class="card-title h2" style="float: left">{{alert.countryName}}</p></span>
</div>
<div class="col">
<span><img src="../../../assets/flags/{{alert.countryCode | lowercase}}.svg" style="width: 40px; height: 28px;"></span>
</div>
</div>
</div>
<p class="card-text">{{alert.alertMessage}}</p>
<p class="card-footer" style="float: right">{{alert.publishedDate | date:'short'}}</p>
</div>
</div>
The text is unusually formatted. One way to use it is to split the string as per your requirement and iterate it using *ngFor.
var alertMessage = '\nAll international flights to Uganda are suspended until 24 April 2020.|\n- This does not apply to:|\n1. Aircraft in a state of emergency.||\n2. Operations related to humanitarian aid, medical and relief flights.||\n3. Technical landings where passengers do not disembark.||\n4. Any other flight that may be so approved by the appropriate authority.||\n';
console.log(alertMessage.split(/[||\n]+/).filter(Boolean)) // <-- `filter(Boolean)` to remove empty strings
You could then use it in the component like following
Service fetching data from API
#Injectable()
export class ApiService {
...
getData() {
this.http.getData().pipe(
.map(data =>
data.forEach(item => {
item.alertMessage = item.alertMessage.split(/[||\n]+/).filter(Boolean)
})
)
);
}
}
Component template
<div class="card" style="width: 69rem;" *ngFor="let alert of jsonValue">
<div class="card-body" #{{alert.countryName}}>
<div class="container">
<div class="row">
<div class="col">
<span> <p class="card-title h2" style="float: left">{{alert.countryName}}</p></span>
</div>
<div class="col">
<span><img src="../../../assets/flags/{{alert.countryCode | lowercase}}.svg" style="width: 40px; height: 28px;"></span>
</div>
</div>
</div>
<p class="card-text">
<ul [ngStyle]="{'list-style': 'none', 'padding-left': '0'}">
<li *ngFor="let message of alert.alertMessage">{{ message }}</li>
</ul>
</p>
<p class="card-footer" style="float: right">{{alert.publishedDate | date:'short'}}</p>
</div>
</div>
May be you want to do some formatting to your data before using it in the template.
The string contains \n and | which has a special meaning. You can use them to format your data.
for Example let say you are getting this data from service inside a method someMethod() . After getting the data loop over the result array elements
and create a new Array for all the response items containing the formatted values.
someMethod(){
.... other lines to fetch the data
let data = {
"countryCode": "BS",
"countryName": "BAHAMAS",
"publishedDate": "2020-03-30T00:00:00.000Z",
"alertMessage": "\nAll international flights to Uganda are suspended until 24 April 2020.|\n- This does not apply to:|\n1. Aircraft in a state of emergency.||\n2. Operations related to humanitarian aid, medical and relief flights.||\n3. Technical landings where passengers do not disembark.||\n4. Any other flight that may be so approved by the appropriate authority.||\n"
}
let arr = str.split('|').filter((el)=>{ return el!== ""}); // splits the string and removes empty element
let newArr = arr.map((el)=>{ return el.replace("\n" ,"")}) // removes \n from string
// of course you can minimise/reduce the logic , this is just to make you understand how the formatting happened
let formattedValues = {
title : newArr[0], // first element is title
subtitle : newArr[1], // second is subtitle
options : newArr.slice(2) // rest is option
}
data['alertMessage'] = formattedValues; // assign the formatted value
}
then in HTML you can use the JSON as below :
<p class="card-text">{{alert.messageData.title}}</p>
<p class="card-text">{{alert.messageData.subtitle}}</p>
<p *ngFor="let it of alert.messageData.options">{{it}}</p>
Here is the working example : Demo

Bolt Network - Codecademy app not interpreting as it should

<div class="main" ng-controller="MainController">
<div class="container">
<div class="content">
<div class="row">
<div class="col-md-3" class="series_img">
</div>
<div class="col-md-6">
<h1 class="series">{{ program.series }}</h1>
<h2 class="episode">{{ program.episode }}</h2>
<p class="description">{{ program.description }}</p>
</div>
<div class="col-md-3">
<ul class="list-group">
<li class="list-group-item"><span>Date:</span>{{ program.datetime | date }} </li>
<li class="list-group-item"><span>On air:</span>{{ program.datetime | day }} </li>
<li class="list-group-item"><span>Time:</span>{{ program.datetime | time }} </li>
<li class="list-group-item"><span>Season:</span>{{ program.season }} </li>
<li class="list-group-item"><span>Genre:</span>{{ program.genre }} </li>
</ul>
</div>
</div>
</div>
</div>
CONTROLLER
app.controller('MainController', ['$scope', function($scope) {
$scope.program = {
series: "Sherlock",
series_img: "img/sherlock.jpg",
genre: "Crime drama",
season: 3,
episode: "The Empty Hearse",
description: "Two years after his reported Reichenbach Fall demise, Sherlock, who has been cleared of all fraud charges against him, returns with Mycroft's help to a London under threat of terrorist attack. John has moved on and has a girlfriend, Mary Morstan. Sherlock enlists Molly to assist him, but when John is kidnapped by unknown assailants and is rescued by Sherlock and Mary, John returns to help find the terrorists and an underground plot to blow up the Houses of Parliament during an all night sitting on Guy Fawkes Night.",
datetime: new Date(2014, 11, 31, 21, 00, 00, 00)
}
}]);
APP
var app = angular.module('BoltNetworkApp', []);
This is what it displays
Here is what it should display
What am I doing wrong? Please help and explain simply as I am a novice. Please and thank you!
if you made this
Make a new folder js/directives/. Inside this folder, create a file js/directives/programListing.js. In this file,create a new directive named programListing:
Use app.directive to create the new directive
Use restrict to create a new Element
Use scope to specify that we'll pass information into this directive through an attribute named listing
Use templateUrl to tell this directive to use the js/directives/programListing.html file
2.
Include this new JavaScript file in the view as a element.
3.
Next, write the directive's template. Make a new file js/directives/programListing.html. Move the HTML from index.html inside the .content div into the directive's template file.
4.
The programListing directive takes in information through the listing attribute. The data in listing becomes available to use in the directive's template. Update the expressions in the directive's template so that it uses listing to display each item.
5.
In the view, use the directive to display the details of program.
6.
Add another object to the controller. Feel free to use your favorite TV show.
7.
Use another directive to display the details of the new object.
change : {{ program.datetime | date }}
to : {{{{ listing.datetime | date }}}}

get nested JSON object in angular js

I'm having a AngularJS spa and want to fetch files from a JSON, which works good so far.
var app = angular.module("MyApp", []);
app.controller("TodoCtrl", function($scope, $http) {
$http.get('todos.json').
success(function(data, status, headers, config) {
$scope.posts = data;
}).
error(function(data, status, headers, config) {
alert("Error");
});
});
and bind it to repeat a list.
<ul ng-repeat="post in posts">
<li>
<b>Name : </b> {{post.name}} <br>
<b>Adress/street :</b> {{post.address.street}}
</li>
</ul>
my problem ist, what if I have nested another object inside the JSON:
"adress": [
{
"street": "somewhat street",
"town": "somewhat town"
}]
My attempt post.adress.street does not work. Any suggestions?
Since address is an array, you have 2 options.
First option:
Use the array notation to access only one of the items in the array. For example:
<ul ng-repeat="post in posts">
<li>
<b>Name : </b> {{post.name}} <br>
<b>Adress/street :</b> {{post.address[0].street}}
</li>
</ul>
Second option:
Iterate over all the address items using another ng-repeat:
<ul ng-repeat="post in posts">
<li>
<b>Name : </b> {{post.name}} <br>
<div ng-repeat="address in post.address">
<b>Adress/street :</b> {{address.street}}
</div>
</li>
</ul>

Play Framework: Html Template content not escaping properly

im trying to populate a list in an html template using a prexisting module
#{Nav.list.map( l =>
l.id match {
case "Art" => { <li id="art"><span>Articles</span></li> }
case "Due" => { <li id="toggle"><span>Links</span>
<div id="drawer">
<div id="drawerContent" style="display:none;">
<ul>
<li><span>link title 2</span></li>
<li><span>link title 3</span></li>
<li><span>link title 4</span></li>
</ul>
</div>
</div>
</li> }
case _ => { <li id="#l.id"><span>#l.title</span></li> }
} )}
the # isnt functioning as an escape character for the final case and instead just gets parsed as #l.id etc i originally did this with nested if else statements with very verbose brackets and that worked but wasnt very nice on the eyes, i think the formatter is having problems with nested scala constructs but im not sure.
i tried using for instead of map and tried enclosing and escaping the match construct, they compile but the issue still remains
I think the issue here is that you are in scala world when doing #{}, thus you can do the following in the last case:
case _ => <li id={l.id}><a href={l.href} title={l.title}><span>{l.title}</span></a></li>
Alternatively I think you can do:
#Nav.list.map( l => ... )