Accessing the data from Json in React Native - json

I am trying to access the data from Nested JSON, but it is showing partial data. JSON Extract and access code are provided below:
JSON
let tableData = [
{ "id":"1",
"title":"Joe's Gelato",
'tagline':"Desert, Ice cream, £££",
'eta':"10-30",
'imgUri':require('./assets/nasi-briyani-mutton.jpg'),
'items':[
{"title":"Gelato",
"contents":[{
"title":"Vanilla" ,
"title":"Chocolate",
"title":"Mint"
}]},
{"title":"Coffee",
"contents":[{
"title":"Flat white" ,
"title":"Latte",
"title":"Caffe Americano"
}]}
]
},
{
"id":"2",
"title":"Joe's Dinner",
'tagline':"Pizza, burgers, £££",
'eta':"50+",
'imgUri':require('./assets/pizza-restaurant.jpg'),
'items':[{
"title":"Pizza",
"contents":[{
"title":"Roco Pizza" ,
"title":"Veggi",
"title":"Chicken Supreme"
}]},
{"title":"Burger",
"contents":[{
"title":"Cubby Burger" ,
"title":"Rock Burger",
"title":"Chicken Lover"
}]
}]
},
];
React Code
<ScrollView>
<TableView>
<Text>---Menu---</Text>
{/* {tableData.map((restaurants,i) => ( */}
{tableData[0].items.map ((menuSection,i) => (
<Section header = {menuSection.title}>
{menuSection.contents.map((dishes,j) => (
<Cell title = {dishes.title}/>
))}
</Section>
))}
</TableView>
</ScrollView>
I am trying to access the last item (contents.title) in nested JSON, but somehow it only shows a partial result instead of the complete list of items. Screen Shot of result is provided below.
It is showing me the last items in the menu instead of showing complete title list as:
- Gelato
Vanilla
Chocolate
Mint
- Coffe
Flat White
Latte
Caffe Americano

Your contents data should be an array then it can map correctly. Currently, it's inside an object, so when you map contents array it has only one object inside. Also, title key inside an object will replace the title with the last value.
Solution - Alter data remove the object and then map.
contents: ['Roco Pizza', 'Veggi', 'Chicken Supreme']
{menuSection.contents.map((dishes, j) => (
<Cell title={dishes} />
))}
I hope this will help you out.

Related

generate many components from an array

I have an array and I need to generate many components as the array lengh:
I tried this but it didn't worked:
let items = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"];
let itemList = [];
items.forEach((item, index) => {
itemList.push(<li key={index}>{item}</li>);
});
export default function TaskList(props) {
return (
<div className="task-list-container">
<Task id="" nombre={itemList} />
</div>
);
}
So I need one component from TaskList that contains Item1 and other Item2 and so one
That's not very clear what you're trying to do...
But I think you should try to loop in the render part instead of stacking components in variables ...
let items=['Item 1','Item 2','Item 3','Item 4','Item 5'];
export default function TaskList(props) {
return (
<div className="task-list-container">
{
items.map((item, index) => <Task key={index} value={item} />)
}
</div>
)
}
It will render as many <Task> components as string in the items array

conditional rendering not acting uniformly in reactjs?

I have used conditional rendering in the past but for some reason, it's working on one element here but not on another although they are both using the same JSON phrasing and the same type of conditional rendering?
JSON array
//Adobe component data
export default[
{
workName: 'Switch up your "Grub" Motiongraphic',
workDescription: 'This is a motion graphic comparing the environmental and health effects of consuming animal products compared to insects as dietary source of protein.',
workTech: ['Adobe After effects'],
videoAddress: ['https://youtu.be/cloat51hzDY'],
Images: []
},
{
workName: 'Simplyfit concept poster',
workDescription: 'This is a poster developed explaining the concept of Simplyfit, a fitness application developed as part of my final year project.',
workTech: ['Adobe Illustrator'],
videoAddress: [],
Images: ['SFPoster.jpg'],
},
{
workName: 'Switch up your "Grub" Infographic',
workDescription: 'This is an infographic developed explaining the benefits of consuming insects as a source of protein.',
workTech: ['Adobe Illustrator'],
videoAddress: [],
Images: ['insectMotiongraphic.png'],
},
{
workName: 'Crunchy Nut Advert spoof',
workDescription: 'This video was made as a comedic spoof of a Crunchy Nut advert',
workTech: ['Adobe Premier Pro'],
videoAddress: ['https://youtu.be/y8S2RUYrLN8'],
Images: [],
},
{
workName: 'Icons and Designs',
workDescription: 'These are a selection of logos and icons created by me.',
workTech: ['Adobe Premier Pro'],
videoAddress: [],
Images: ['Mylogo.png'],
},
]
The problem I'm having is with the 'videoAdress' and the 'Images' I've tried setting null values undefined etc for them both but for the images the only thing that stops them from rendering is setting the value as [] but this doesn't work for the videoAdress the iframe is still rendered?
React js code
{Data.map((Projects, index) => {
return <div className='Cards'>
<Carousel showThumbs={false} infiniteLoop={true} swipeable={false} emulateTouch={false} showStatus={false} autoPlay={slideShow} dynamicHeight={false}>
{Projects.Images && Projects.Images.map((Image, index) => { return <div className='image-iframeContainer'><img src={require("../assets/Port-images/Adobe/" + Image)} /></div> })}
{Projects.videoAddress && <div className='image-iframeContainer'><ReactPlayer url={Projects.videoAddress} muted={false} controls={false} onPlay={autoplayChange} onPause={autoplayChange} onEnded={autoplayChange} /></div>}
</Carousel>
{Projects.webAddress && <div className='webButton'><LinkIcon onClick= { () => {window.open(Projects.webAddress);}}/></div>}
<h1>{Projects.workName}</h1>
{Projects.workTech.map((Tech, index) => { return <p className='techList'>{Tech}</p> })}
<div className='descriptionContainer'>
<p className='description'>{Projects.workDescription}</p>
</div>
</div>
})}
The function I would like is for the Images and Videos only to render if there is a stored address I'm sure I'm missing something very silly but still, I've been stuck on this for awhile.
Conditional rendering works by casting the condition to a truthy value. For example:
Projects.Images && <Component />
is equal to this:
!!Project.Images && <Component />
Now if you do this for an empty array [], the truthy value is TRUE. This means that <ReactPlayer /> is rendered with [] value and the <img /> is not rendered because [].map() doesn't run on an empty array.
To fix this do this instead:
{Projects.Images && Projects.Images.length > 0 && Projects.Images.map((Image, index) => {
return <div className='image-iframeContainer'>
<img src={require("../assets/Port-images/Adobe/" + Image)} />
</div>
})}
{Projects.videoAddress && Projects.videoAddress.length > 0 &&
<div className='image-iframeContainer'>
<ReactPlayer url={Projects.videoAddress[0]} muted={false} controls={false} onPlay={autoplayChange} onPause={autoplayChange} onEnded={autoplayChange} />
</div>}
I noticed that your videoAddress doesn't use the map() method, but I guess it's a typo

React Render HTML object from JSON object

I have to render html object Array in React JS
Can anyone guide me how to use renderHTML function.
output of the object is something like this:
"
const items = this.state.Data.map(item => (
<div key={item._id}>{renderHTML("{item.albComEn}")}</div>
another variation i tried
const items = this.state.Data.map(item => (
<div key={item._id}>{renderHTML("item.albComEn")}</div>
));
output i get => "item.albComEn"
or
{item.albComEn}
You can try with template strings. More info
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
const items = this.state.Data.map(item => (
<div key={item._id}>{renderHTML(`${item.albComEn}`)}</div>
You can also use short syntax of React Fragments i.e. '<> </>'. Use these to bracket to write the html code. When rendered the html code will successfully compiled.
Example:
const service = [
{
htmlCode: <>
<div>
<h2>Application Screening</h2>
<br />
<br />
What you can expect from us:<br />
- Your resume will be written by a team of seasoned experts<br />
- They will make sure that your Resume presents your strong points,
achievements & key skills in a recruiter-friendly format.<br />
</div>
</>
},
]
Use inside render method as
...
render(
<div>
{service[0].htmlCode}
<div>
)
}

Is there a method to display data from api where the id key is taken from another key?

JSON Data:
"abcd":[
{
"id":"1",
"cityId":"2",
},
{
"id":"2",
"cityId":"3",
}
],
"city":[
{
"id":"2",
"cityName":"california"
},
{
"id":"3",
"cityName":"vicecity"
}
]
Angular:
<div *ngFor="let clg of abcd$">
<p>
{{clg.cityId}}
<!-- Here i need to print the cityname from city by using the cityId we have got from abcd -->
</p>
</div>
app.component.ts:
ngOnInit() {
this.data.getColleges().subscribe(
data => this.abcd$ = data
)
}
fetching data from "abcd" is perfectly working....and no problem in fetching the datas from "city" too. But is it possible to fetch the cityName from "city" by using the cityId key from the "abcd" section.
You can use a method to get city by ID:
app.component.ts:
getCityByID = (cityID) => {
return this.city$.find(item => item.id === cityID);
}
Template:
<div *ngFor="let clg of abcd$">
<p>
{{ clg.cityId }}
{{ getCityByID(clg.cityId).cityName }}
</p>
</div>
Update
As far as I understand, you are fetching colleges and cities with 2 separate observables. Because of this, when you are trying to get city by ID, it may (or may not) throw an error if second observable has not been resolved yet. So, you need to combine/join these two streams together. I prefer combineLatest to do this but forkJoin will work as well.
In app.component.ts:
import { combineLatest } from 'rxjs';
......
ngOnInit() {
combineLatest(
this.data.getColleges(),
this.data.getCity()
).subscribe(([colleges, cities]) => {
this.abcd$ = colleges;
this.city$ = cities;
});
}
This way, you make sure that both abcd$ and city$ are inited. Hope this helps.
For further reading:
combineLatest: https://www.learnrxjs.io/operators/combination/combinelatest.html
forkJoin: https://www.learnrxjs.io/operators/combination/forkjoin.html

angular 2 ngFor Cannot read property of undefined

I have a nested object with data that I am trying to access with ngFor.
I am able to reach the first part of the data with the first ngFor (app_name, time_stamp etc)
But for some reason I am not getting to the nested object of test_cases. When I try it breaks the whole page and the console keeps telling me "Cannot read property 'test_cases' of undefined" and I can't seem to figure out why...
(first part of) data inside the component:
export class AppComponent {
tests = TESTS;
var TESTS: Test[] = [
{
"app_name": "website",
"time_stamp": "2018-01-20T12:00:00Z",
"test_cases": [
{
"test_name": "View article",
"status": true,
}]
}]
HTML partial:
<div id="tested-app" *ngFor = "let item of tests">
<h2>----<span> {{ item.app_name }} </span>----</h2>
<p id="time"> Time: <span> {{item.time_stamp}} </span> </p>
</div>
<div class="module" *ngFor="let subItem of item.test_cases">
<h3>{{subItem.test_name}}</h3>
</div>
For peeps who are struggling with this:
John Montgomery and Andres M answered this in the comments, I had to put the second div inside the first.