Hey I am a beginner in react trying to make my first full stack app, I am fetching data from mongodb using axios and storing data in fetchedjobs array. Jobtitle array only has the title property of the fetchedjobs and I want to print all the entries but not able to. For now I am printing these elements by hard coding the indexes {this.state.jobtitle[0]} .
Please Help
class FindJob extends Component{
constructor(props){
super(props);
this.state={
fetchedjobs:[],
jobtitle:[],
}
}
componentDidMount(){
axios.get(' http://localhost:4002/api/findjob')
.then(res=>{
this.setState({
fetchedjobs:res.data
})
let jobtitle=[]
this.state.fetchedjobs.map(fetchedjob=>
jobtitle.push(fetchedjob.jobtitle)
)
console.log(jobtitle[0])
this.setState({
jobtitle
})
})
}
render(){
return(
<div className="content">
<h5>{this.state.jobtitle[0]}</h5>
</div>
);
}
}
export default FindJob;
fetched json
[
{
"_id": "600469700459a40c088f3dde",
"jobtitle": "swe",
"company": "ibm",
"officelocation": "ggn",
"jobtype": "Part Time",
"publisher": "sid",
"date": "2021-01-17T16:44:32.084Z",
"__v": 0
},
{
"_id": "600469aa0459a40c088f3ddf",
"jobtitle": "janitor",
"company": "cisco",
"officelocation": "delhi",
"jobtype": "Full Time",
"publisher": "tanmya",
"date": "2021-01-17T16:45:30.218Z",
"__v": 0
},
{
"_id": "60046ae8b95ae81c14278f9e",
"jobtitle": "fljdk",
"company": "ndkf",
"officelocation": "mdfkfm",
"jobtype": "Part Time",
"publisher": "tanmya",
"date": "2021-01-17T16:50:48.311Z",
"__v": 0
}
]
You can create sync call in setState method and try it,
axios.get(' http://localhost:4002/api/findjob')
.then(res=>{
this.setState({ fetchedjobs:res.data }, () => {
let jobtitle=[]
this.state.fetchedjobs.map(fetchedjob=>
jobtitle.push(fetchedjob.jobtitle)
)
this.setState({ jobtitle})
})
})
Try this:
render(){
return(
<div className="content">
{this.state.jobtitle.length?this.state.jobtitle.map((item)=>{
return <h5>{item._id}</h5> //here you can display any property that you wish to
})
:null}
</div>
);
}
Related
I apologise as this is probably either very basic or i've done something compeltely wrong. I'm brand new to React, and coding in general, and I'm trying to make a React app that shows the recipes im using on cards. The cards in turn should be searchable and dynamic, dissapearing if they don't match etc.
This is my app.js file, that when run, it just brings up my custom "Loading" screen without data. Where have I messed up on this?
import React, {Component} from 'react';
import CardList from './CardList';
import SearchBox from './SearchBox';
import Scroll from "./Scroll";
import "./App.css"
class App extends Component {
constructor() {
super()
this.state = {
recipes: [],
searchfield: "",
}
}
componentDidMount() {
fetch("./recipedata.json")
.then(response => { return response.json();})
.then(recipedata => {this.setState({recipes: recipedata})});
}
onSearchChange= (event) =>{
this.setState({searchfield: event.target.value})
}
render() {
const filteredRecipe = this.state.recipes.filter(recipes =>{
return recipes.name.toLowerCase().includes(this.state.searchfield.toLowerCase());
})
if (this.state.recipes.length === 0) {
return <h1 class="f1 tc">Loading</h1>
} else {
return(
<div className="tc">
<h1 className="f1">Recipes</h1>
<SearchBox searchChange={this.onSearchChange} />
<Scroll>
<CardList recipe={filteredRecipe}/>
</Scroll>
</div>
)
}
}
}
export default App
Thanks in advance
edit: I have been asked to post the contents of recipedata.json:
[
{
"id" : 1,
"name" : "Carrot cake",
"type" : "sweet",
"author" : "Grandma",
"link" : "recipes/carrotcake.html"
},
{
"id" : 2,
"name" : "Spicy chicken pitta filling",
"type" : "savoury",
"author" : "Grandma",
"link" : "recipes/chickenpitta.html"
},
{
"id" : 3,
"name" : "Mushroom ham and chicken crusty puff pies",
"type" : "savoury",
"author" : "Grandma",
"link" : "recipes/crustypuff.html"
},
{
"id" : 4,
"name" : "Sweet potato pumpkin seed rolls",
"type" : "savoury",
"author" : "Grandma",
"link" : "recipes/sweetpotrolls.html"
},
{
"id": 5,
"name": "Wild mushroom wafer",
"type": "savoury",
"author" : "Grandma",
"link": "recipes/mushroomwafer.html"
},
{
"id": 6,
"name": "Piri Piri chicken sauce",
"type": "savoury",
"author": "Grandma",
"link": "recipes/piriRecipe.html"
},
{
"id": 7,
"name": "Chicken Liver Pate'",
"type": "savoury",
"author": "Grandma",
"link": "recipes/pate.html"
},
{
"id": 8,
"name": "Creamy mushroom pasta",
"type": "savoury",
"author": "Grandma",
"link": "recipes/mushroompasta.html"
},
{
"id": 9,
"name": "Cheesey garlic bread",
"type": "savoury",
"author": "Grandma",
"link": "recipes/gbread.html"
},
{
"id": 10,
"name": "Mini quiches",
"type": "savoury",
"author": "Grandma",
"link": "recipes/miniquiche.html"
},
{
"id": 11,
"name": "Sticky lemon ginger cake",
"type": "sweet",
"author": "Grandma",
"link": "recipes/stickyrecipe.html"
},
{
"id": 12,
"name": "Sticky toffee pudding",
"type": "sweet",
"author": "Grandma",
"link": "recipes/stickytoffee.html"
},
{
"id": 12,
"name": "Iced cream buns",
"type": "sweet",
"author": "Grandma",
"link": "recipes/icedcreambuns.html"
},
{
"id": 13,
"name": "Pineapple Cake",
"type": "sweet",
"author": "Grandma",
"link": "recipes/pineapplecake.html"
}
]
Edit 2:
Thanks for your help all, I've now fixed the app.js file and the Json is being returned. I'm now faced with this error in my CardList.js component:
TypeError: Cannot read property 'map' of undefined
CardList
C:/Users/mattj/OneDrive/Desktop/coding/gmcb-react-app/src/CardList.js:5
2 | import Card from './Card.js';
3 |
4 | const CardList = ({recipes}) => {
> 5 | return <div>
6 | {recipes.map((recipedata, i) => {
7 | return(
8 | <Card
code:
import React from 'react';
import Card from './Card.js';
const CardList = ({recipes}) => {
return <div>
{recipes.map((recipedata, i) => {
return(
<Card
key={i}
id={recipes[i].id}
name={recipes[i].name} />
)
})}
</div>
}
export default CardList
What have I messed up here?
Regarding issue #2 you posted it is really tough to say, however I think you are overcomplicating things with your card list. You should simply pass an array of filtered recipes to your component.
Your card list component you should just pass an entire recipe option to the component instead of trying to pass specific props. If in the future you add more keys to each recipe object you wont have to adjust your card list
const CardList = ({recipes}) => {
return (
<div>
{
recipes.map(recipe => {
return <Card recipe={recipe} key={recipe.id} />
})
}
</div>
)
}
Inside your card component you can destructure the keys off the recipe object
const Card = ({recipe}) => {
return (
<div>
<h3>{recipe.name}</h3>
<p>{recipe.type} - {recipe.author}</p>
<hr />
</div>
)
}
I made you a code sandbox, I used React Hooks and a mockAxios call in order to fake what a server would do and so you have some code for if you want to call an API in the future.
https://codesandbox.io/s/broken-glitter-4wb61?file=/src/App.js
You don't need to use fetch to get the data from the local json file.
You can simply import the contents of ./recipedata.json by doing this:
import recipedata from './recipedata.json';
And then change your componentDidMount to this:
componentDidMount() {
this.setState({ recipes: recipedata });
}
You mostly use fetch when you are trying to fetch data from a http server. Read more here and here
To support #Qubaish Bhatti's comment, yes, there is no need to have recipes in state. You can use it directly and do away with this.state.recipes
I am trying to list the server response , but some mistake is their in my code about accessing nested json..Following is the structure of json
Updated:
{
"child": [],
"courses": [{
"data": {
"name": "Student 1",
"date_created": 1514610451,
"total_students": 4,
"seats": "",
"start_date": false,
"categories": [{
"name": "Subject",
"slug": "Subject"
}],
"intro": {
"id": "1",
"name": "Main Admin",
"sub": ""
},
"menu_order": 0
},
"headers": [],
"status": 200
}]
}
And my react part is
render(){
return this.state.course.map(course =>
<Text style={styles.userStyle}>{course.courses.data.map(datas => datas.name)}</Text>
);
}
Please help me to figure out the mistake.I am getting this.state.course.map is not a function.My fetch request is as follows
state= {course:[]};
componentWillMount(){
fetch('https://www.mywebsite.com/' + this.props.navigation.state.params.id)
.then((response) => response.json())
.then((responseData) => this.setState({course: responseData}))
}
So you would need to show us how this.state is set, but if you're doing something like this.setState(jsonObject), the property you are looking for seems to be this.state.courses. This would access the array of courses. However, in the subsequent lines you try to access course.courses, which suggests you're setting the state like this.seState({course: jsonObject}) so it's not clear.
I'd say if you fix the first problem, you'll immediately hit another one because it doesn't look like data is an array but an object, so trying to call map on it is unlikely to do what you want (unless you've been playing with prototypes).
EDIT:
In response to the new info, I recommend the following:
render(){
if(this.state.course && this.state.course.courses) {
return this.state.course.courses.map(course =>
<Text style={styles.userStyle}>{course.data.name}</Text>
);
} else {
return [];
}
}
I'm newbie to Angular JS.
I am using Angular 2 in my project.
My JSON data is in below
"locations": [
{
"id": "ASS",
"name": "test center",
"city": "Staten Island",
"zip": "10301",
"state" : "texas"
},
{
"id": "ASD",
"name": "test center1",
"city": "Staten Island",
"zip": "10301",
"state" : "Florida"
},
{
"id": "AAY",
"name": "test center2",
"city": "Staten Island",
"zip": "10301",
"state" : "Florida"
},
{
{
"id": "ASD",
"name": "test center1",
"city": "Staten Island",
"zip": "10301",
"state" : "Florida"
}
],
I want to display data group by state.
texas : <div>ASS</div>
florida : <div>ASD</div>
<div>AAY</div>
<div>ASD</div>
group.pipe.ts:
#Pipe({name: 'groupBy'})
export class GroupByPipe implements PipeTransform {
transform(value: Array<any>, field: string): Array<any> {
console.log('test');
const groupedObj = value.reduce((prev, cur)=> {
if(!prev[cur[field]]) {
prev[cur[field]] = [cur];
} else {
prev[cur[field]].push(cur);
}
return prev;
}, {});
return Object.keys(groupedObj).map(key => ({ key, value: groupedObj[key]
}));
}
location.component.ts:
import {GroupByPipe} from '../group.pipe';
#NgModule({
declarations : [GroupByPipe]
})
My error :
Unhandled Promise rejection: Template parse errors:
The pipe 'groupBy' could not be found (" <div class="col-sm-12 left_otr">
<div class="col-md-6 col-sm-6 left" *ngFor="let [ERROR ->]item
of pagedItems | groupBy : 'state'">
How to solve this?
Just Passed the array and field to the below code:
transform(value: Array<any>, field: string): Array<any> {
const groupedObj = value.reduce((prev, cur)=> {
if(!prev[cur[field]]) {
prev[cur[field]] = [cur];
} else {
prev[cur[field]].push(cur);
}
return prev;
}, {});
return Object.keys(groupedObj).map(key => ({ key, value: groupedObj[key] }));
}
didn't used pipes.
updated my html as like below:
<div *ngFor="let item1 of pagedItems">
<h1>{{item1.key}}</h1>
<div *ngFor="let item of item1.value">
// my logic is here.
</div
I have tried looking on many sites and browsed through many posts here, but still can't find what I am looking for, or at least could not implement it work. I have an API response where depending on the request parameters it either returns an object with an array of objects (which I am able to deal with), or an object with several objects that contain arrays within them. I was able to get the data from the simple form, but the multi-object containing object is kicking my butt. I am also doing this in Angular 4, just in case that makes a difference. The response is from the holiday api.
Below is the full response with no filtering params, minus a few objects, to not beat a dead horse.
{ "status": 200, "holidays": {
"2016-01-01": [
{
"name": "Durin's Day",
"date": "2016-01-01",
"observed": "2016-01-01",
"public": true
}
],
"2016-02-23": [
{
"name": "Founder's Day",
"date": "2016-02-23",
"observed": "2016-02-23",
"public": true
}
],
"2016-02-29": [
{
"name": "Leap Day",
"date": "2016-02-29",
"observed": "2016-02-29",
"public": false
}
],
"2016-03-20": [
{
"name": "Weasel Stomping Day",
"date": "2016-03-20",
"observed": "2016-03-20",
"public": false
}
],
"2016-04-05": [
{
"name": "First Contact Day",
"date": "2016-04-05",
"observed": "2016-04-05",
"public": false
}
],
"2016-04-06": [
{
"name": "Second Contact Day",
"date": "2016-04-06",
"observed": "2016-04-06",
"public": false
}
],
"2016-05-10": [
{
"name": "Whacking Day",
"date": "2016-05-10",
"observed": "2016-05-10",
"public": false
}
],
"2016-10-31": [
{
"name": "Harry Potter Day",
"date": "2016-10-31",
"observed": "2016-10-31",
"public": false
}
],
"2016-11-24": [
{
"name": "Hogswatch",
"date": "2016-11-24",
"observed": "2016-11-24",
"public": false
}
],
"2016-12-23": [
{
"name": "Festivus",
"date": "2016-12-23",
"observed": "2016-12-23",
"public": true
}
],
"2016-12-25": [
{
"name": "Decemberween",
"date": "2016-12-25",
"observed": "2016-12-25",
"public": false
},
{
"name": "Winter Veil",
"date": "2016-12-25",
"observed": "2016-12-26",
"public": true
}
]
} }
Here is the code used:
import { Component, OnInit, Input } from '#angular/core';
import { HolidayService } from '../holiday.service';
#Component({
selector: 'app-holiday',
templateUrl: './holiday.component.html',
styleUrls: ['./holiday.component.css']
})
export class HolidayComponent implements OnInit {
constructor(private _holiday: HolidayService) {
}
holidaysObj: any;
holidayArr: Array<{key: string, value: string}>;
ngOnInit() {
}
holidayParams(country,month){
this._holiday.getHolidays(country.value,month.value)
.subscribe(responseDa
ta => {
this.holidaysObj = responseData;
console.log(responseData);
});
this.convertObj(this.holidaysObj);
}
convertObj(obj : any){
for(const prop in obj){
if(obj.hasOwnProperty(prop)){
this.holidayArr.push(obj[prop]);
}
}
}
}
It works just fine when the response is called with filtering params, like 'month' and returns something like this:
{
"status": 200,
"holidays": [
{
"name": "Festivus",
"date": "2016-12-23",
"observed": "2016-12-23",
"public": true
},
{
"name": "Decemberween",
"date": "2016-12-25",
"observed": "2016-12-25",
"public": false
},
{
"name": "Winter Veil",
"date": "2016-12-25",
"observed": "2016-12-26",
"public": true
}
]
}
You can use a custom pipe to iterate your Objects, you could also extract the data from holidays from your response like:
.map(res => res.json().holidays)
but here I won't do it.
So let's create the custom pipe:
#Pipe({
name: 'keys'
})
export class KeysPipe implements PipeTransform {
transform(value: any, args?: any[]): any[] {
// check there is value to iterate
if(value) {
// create instance vars to store keys and final output
let keyArr: any[] = Object.keys(value),
dataArr = [];
// loop through the object,
// pushing values to the return array
keyArr.forEach((key: any) => {
dataArr.push(value[key]);
});
// return the resulting array
return dataArr;
}
}
}
and then you can use it in the template like:
<div *ngFor="let d of data?.holidays | keys">
<div *ngFor="let a of d">
{{a.name}}
{{a.date}}
<!-- rest of the properties -->
</div>
</div>
Here's a
Demo
UPDATE:
Alternatively, if you want to make your data to the same format as the other data you are receiving, you can manipulate the response. Like you mentioned, you need an if else statement first to check in which format the data is. In case the data is in the format like presented in question, you can do the following to reach the desired result:
.subscribe(data => {
// add statuscode
this.data = {status:data.status,holidays:[]}
let keyArr: any[] = Object.keys(data.holidays);
keyArr.forEach((key: any) => {
// push values of each holiday
this.data.holidays.push(data.holidays[key][0]);
});
})
Demo
I generate the routing of my app with the help of a data object which contains information about the routes, the desired path (slug), the according component and eventually sub-routes (nestedRoutes). If a route has nested routes I would like to pass them to the component as a data object and use them in the component e.g. for a sidebar navigation.
The routing is working fine, but I don’t get the data nestedRoutes={route.nestedRoutes} passed to the component.
If you like please take a look at my code snippet:
var data = {
"routes": [
{
"title": "MLS Styleguide",
"slug": "/mls-styleguide",
"component": MLSStyleguide,
"nestedRoutes": [
{
"title": "Basic Typography",
"slug": "/mls-styleguide",
"component": Typography,
"isIndexRoute": true
},
{
"title": "Form & Fields",
"slug": "/mls-styleguide/forms-fields",
"component": FormsFields
},
{
"title": "Form Sections",
"slug": "/mls-styleguide/form-sections",
"component": FormSections
},
{
"title": "Filters",
"slug": "/mls-styleguide/filters",
"component": Filters
},
{
"title": "Side Panels & Containers",
"slug": "/mls-styleguide/side-panels-containers",
"component": SidePanelsContainers
},
{
"title": "Tiles & Content",
"slug": "/mls-styleguide/tiles-content",
"component": TilesContent
},
{
"title": "Tooltips & Notifications",
"slug": "/mls-styleguide/tooltips-notifications",
"component": TooltipsNotifications
}
]
},
{
"title": "Playground",
"slug": "/playground",
"component": Playground
}
]
}
module.exports = (
<Route path="/" component={App}>
<IndexRoute component={Home}/>
{data.routes.map(
function(route) {
if (route.nestedRoutes) {
return (
<Route path={route.slug} nestedRoutes={route.nestedRoutes} key={route.title} component={route.component}>
{route.nestedRoutes.map(
function(nestedRoute) {
if (nestedRoute.isIndexRoute) {
return (
<IndexRoute key={nestedRoute.title} component={nestedRoute.component}/>
)
} else {
// {console.log(nestedRoute.slug)}
return (
<Route path={nestedRoute.slug} key={route.title} component={nestedRoute.component}/>
)
}
}
)}
</Route>
)
} else {
// console.log(route.slug)
return <Route path={route.slug} foo="bar" key={route.title} component={route.component}/>
}
}
)}
</Route>
)
Any comment or hint in the right direction is welcome, thanks!
EDIT
Code of the receiving component.
Please don’t wonder! The links data in the getInitialState() function serves as a workaround at the moment. When the component actually receives the this.props.nestedRoutes this will be removed.
I hope you get the idea!
export default React.createClass({
getInitialState(){
return {
links: [
{
"title": "Basic Typography",
"slug": "/mls-styleguide/"
},
{
"title": "Form & Fields",
"slug": "/mls-styleguide/forms-fields"
},
{
"title": "Form Sections",
"slug": "/mls-styleguide/form-sections"
},
{
"title": "Filters",
"slug": "/mls-styleguide/filters"
},
{
"title": "Side Panels & Containers",
"slug": "/mls-styleguide/side-panels-containers"
},
{
"title": "Tiles & Content",
"slug": "/mls-styleguide/tiles-content"
},
{
"title": "Tooltips & Notifications",
"slug": "/mls-styleguide/tooltips-notifications"
},
]
}
},
render() {
return (
<div>
<Sidebar className="left">
<SideNavbar links={this.state.links}/>
{/*<SideNavbar links={this.props.nestedRoutes}/>*/}
</Sidebar>
<div className="content-container">
{console.log(this.props.nestedRoutes)}
<h2>MLS Styleguide</h2>
{this.props.children}
</div>
</div>
)
}
})
It seems that I am not able to understand the provided solutions.
But I found a workaround: I just took the data, put it in a separate file and imported it in both files. It serves the purpose, it is simple and it is done.
Thank you all for your support!