Having issues using axios to handle my JSON data - node.js

I am trying to setState from this data,
var axios = require('axios');
import Trails from './trails';
import React, { Component } from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
trails: []
}
}
componentWillMount() {
axios
.get('https://www.mtbproject.com/data/get-trails-by-id?ids=2081068,830442%208013961&key=(API-KEY)')
.then(response => response.data)
.then(trails => this.setState({trails}));
}
which looks like this:
{
"trails": [
{
"id": 2081068,
"name": "San Dieguito River Park - Bernardo Bay\/ Piedras Pintadas Trail",
"type": "Featured Ride",
"summary": "Sweet little loop of singletrack trails.",
"difficulty": "blue",
"stars": 3.6,
"starVotes": 24,
"location": "Escondido, California",
"url": "https:\/\/www.mtbproject.com\/trail\/2081068\/san-dieguito-river-park-bernardo-bay-piedras-pintadas-trail",
"imgSqSmall": "https:\/\/cdn-files.apstatic.com\/mtb\/2148715_sqsmall_1372258680.jpg",
"imgSmall": "https:\/\/cdn-files.apstatic.com\/mtb\/2148715_small_1372258680.jpg",
"imgSmallMed": "https:\/\/cdn-files.apstatic.com\/mtb\/2148715_smallMed_1372258680.jpg",
"imgMedium": "https:\/\/cdn-files.apstatic.com\/mtb\/2148715_medium_1372258680.jpg",
"length": 8.2,
"ascent": 570,
"descent": -567,
"high": 488,
"low": 317,
"longitude": -117.0766,
"latitude": 33.0512,
"conditionStatus": "All Clear",
"conditionDetails": "Dry",
"conditionDate": "2018-09-11 09:12:17"
}
],
"success": 1
}
Then I am trying to map it like this:
render() {
return (
<div className='App'>
<div className="container">
<div className="jumbotron">
<h4>Mtb</h4>
<p>Trails:</p>
</div>
{this.state.trails.map(trail => (
<Trails key={trail.id}
conditions={trail.conditionDetails}
/>
))
}
</div>
</div>
);
}
}
I then get an error saying that my map method is not a function. Can someone point out what I am doing wrong?
When I console.log my state it appears that it is not being set, might this be the issue and be the explanation for why it is not working?

You are setting trails to be the entire data object you get in response to your request. Use the trails property of the data object instead.
componentWillMount() {
axios
.get('https://www.mtbproject.com/data/get-trails-by-id?ids=2081068,830442%208013961&key=(API-KEY)')
.then(response => this.setState({ trails: response.data.trails }));
}

Related

useContext() returns undefined values -

I have a context file and state file for Products. when I try to use that context in products component it is returning undefined values
productContext.js
import { createContext } from "react";
const ProductContext = createContext();
export default ProductContext;
ProductState.js
import ProductContext from './productContext';
import { useState } from 'react';
const ProductState = (props) => {
const productsInitial = [
{
"_id": "63a4cc857f40d0063116be5f",
"user": "63a4cbfd7f40d0063116be5d",
"title": "Cassava",
"description": "On-demand sand castle construction expertise.",
"imgURL": "null",
"price": "30",
"__v": 0
},
{
"_id": "63a4ccad7f40d0063116be69",
"user": "63a4cbfd7f40d0063116be5d",
"title": "Soyabeans",
"description": "On-demand sand castle construction expertise.",
"imgURL": "null",
"price": "30",
"__v": 0
}
]
const [products, setProducts] = useState(productsInitial);
// console.log(products);
return (
<>
<ProductContext.Provider value={{ products, setProducts }}>
{props.children}
</ProductContext.Provider>
</>
)
}
export default ProductState;
ProductComponent.js (react component)
import React, { useContext } from 'react';
import ProductContext from '../context/products/productContext';
import ProductItems from './ProductItems';
console.log(ProductContext);
const ProductComponent = () => {
const context = useContext(ProductContext);
const { products, setProducts } = context;
return (
<>
<div className="col-lg-4 ">
{products.map((product) => {
return <ProductItems product={products} />
})}
</div>
</>
)
}
export default ProductComponent;
the line
const context = useContext(ProductContext);
in Products.js Component is returning undefined value because ProductContext is returning undefined
Component that use the context must be wrapped using ProductState component
If you don't know where to add ProductState you can add in your entry point file.
root.render((
<ProductState>
<App />
</ProductState>
))
You can simplify the object destructuring
const { products, setProducts } = useContext(ProductContext);

Trying to display single user

I'm trying to create this logic a whole day and can't find anything helpful.. A small introduce of my app: While studying, I'm creating my local date app as practical job to improve more skills and logics. The problem is that I'm trying to get single user in main(home) page, when user login it should see already loaded single user from MongoDB where he can click like or dislike button. When user clicks one of them this user will push in user liked or dislike array and next user displays. I don't have like system yet, cause I can't get a single user. So later I wanna do filter method if user already liked or disliked other user, that one user didn't appear anymore and let users view his liked and disliked users.
So the main thing is that I have a get method where I'm getting all users and tried to create different routes to get only one of them, but can't imagine how to create correct logic of that.. 4-5 hours ago I tried to make for, map, forEach cycles but still can't understand the main logic here..
Here's my code, if it's not enough to understand just ask me for more code.
mainController(back-end):
getSingleUser: async (req, res) => {
const { secret } = req.params;
const findUser = await UserSchema.findOne({ secret });
if (findUser) {
return res.send({ error: false, message: 'User found', data: findUser });
}
return res.send({ error: true, message: 'User not found', data: null });
},
getAllUsers: async (req, res) => {
try {
const allUser = await UserSchema.find({});
res.status(200).json(allUser);
} catch (error) {
res.status(400).json({ message: error.message });
}
}
mainRouter(back-end):
const express = require('express')
const { login, register, getSingleUser, getAllUsers } = require("../controller/mainController")
const { loginValidate, registerValidate } = require("../middleware/authValidator")
const mainRouter = express.Router()
mainRouter.post('/register', registerValidate, register);
mainRouter.post('/login', loginValidate, login);
mainRouter.get('/api', getAllUsers)
mainRouter.get('/user/:secret', getSingleUser)
module.exports = mainRouter;
HomePage(front-end):
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import Toolbar from '../components/Toolbar';
import { get } from '../helper/helper';
import SingleUser from '../components/SingleUser';
export default function HomePage() {
const [allUsers, getAllUsers] = useState([])
const secret = window.localStorage.getItem('secret')
useEffect(() => {
async function fetchUsers() {
const resp = await get('api')
getAllUsers(resp)
}
fetchUsers()
}, [])
return (
<div className='home__page'>
<Toolbar />
<div className="home__users">
{allUsers && allUsers.filter(user => user.secret !== secret).map((users, i) => <SingleUser users={users} key={i} />)}
</div>
<footer className='footer'>
<p>All rights reserved by Cartoon Match organization. To read more about our policy <Link to='/policy'>click here</Link>. </p>
</footer>
</div>
)
}
This is result of HomePage users fetch:
[
{
"_id": "638e31a2579ba2a13b454943",
"image": [
"https://picsum.photos/id/377/4884/3256",
"https://picsum.photos/id/378/5000/3333"
],
"username": "testas",
"firstName": "testas",
"lastName": "testas",
"email": "test#gmail.com",
"gender": "male",
"city": "asdadas",
"country": "aasdasd",
"birth": "2020-02-20",
"phone": "65asd15a6sd",
"password": "$2b$04$zpqQVU7cFUfdA9DCfKmFYOOdY93OVPXoQq08kM87ehwwxD25/pl6q",
"likes": [],
"liked": [],
"secret": "Ey2_-dVlpg",
"__v": 0
},
{
"_id": "639130a43c2e51dc08531019",
"image": [
"https://www.1zoom.me/big2/98/183590-20043.jpg",
"https://pngimg.com/uploads/shrek/shrek_PNG22.png"
],
"username": "SirShrek",
"firstName": "Sir",
"lastName": "Shrek",
"email": "callmeshrek#swamp.com",
"gender": "male",
"city": "Swamp",
"country": "Fairy-Tale Land Of Duloc",
"birth": "1999-02-27",
"phone": "830-476-5664",
"password": "$2b$04$u1jacGrx6yWOMxfkllMxWO.5in4rQDFIbbCMMixzHqV9rObtq1tKG",
"likes": [],
"liked": [],
"secret": "FP8Rd4izgQ",
"__v": 0
},
{
"_id": "6391c8df7f83052432e2d939",
"image": [
"https://static.wikia.nocookie.net/vsbattles/images/e/e8/Dexter_Rendered.png/revision/latest?cb=20180919045250",
"https://i.ebayimg.com/images/g/VesAAOSwrohehKhn/s-l1600.jpg"
],
"username": "Dexter",
"firstName": "Dexter",
"lastName": "Michael Louis McPherson lll",
"email": "dexter#science.com",
"gender": "male",
"city": "Genius Grove",
"country": "Peter Lorre",
"birth": "2014-12-31",
"phone": "555-0100",
"password": "$2b$04$BMUidKOaRBtWDNKH.NduB.gkgzUhPNuXVk10ip7lPo/N/1k/8sxvW",
"likes": [],
"liked": [],
"dislike":[],
"secret": "9k6ilC2ZZg",
"__v": 0
}]
This is SingleUser component:
import React, { useEffect, useState } from "react";
import MainContext from '../context/MainContext'
import { get, put } from '../helper/helper'
export default function SingleUser({ users }) {
return (
<div className='single__user'>
<img src={users.image[0]} alt="" />
<h3>{users.firstName} {users.lastName}</h3>
<h4>{users.gender}</h4>
<button>Dislike</button>
<button onClick={postLikes}>Like</button>
</div>
);
}

Datatable server side processing in react js

I tried to add jquery datatable in react with server side processing. I'm new to react so, i can't find any better module to implement this. I tried following code its not returning any error but, data not loading into table even data retrieved correctly from endpoint.
import React, {Component} from 'react';
import '../assets/css/datatable.css';
const $ = require('jquery');
$.DataTable = require('datatables.net');
class Table extends Component {
componentDidMount() {
$(this.refs.main).DataTable({
dom: '<"#example">',
processing: true,
language: {
"processing": 'Loading...'
},
serverSide: true,
ajax: {
url: 'http://localhost:5001/endpoint',
type: 'post',
dataSrc: ""
},
columns: [
{ "title": "value", "name":"value", "data": "value", "className":"link text-left text-nowrap" },
{ "title": "created_at", "name":"createdAt", "data": "createdAt", "className":"link text-left text-nowrap", "visible": false, "searchable": false}
]
});
}
render() {
return (
<div>
<table ref="main" />
</div>);
}
}
export default Table;
Please, help me to resolve this issue. Thank you in advance.
My API response like below.
{
"draw": 1,
"recordsTotal": 57,
"recordsFiltered": 57,
"data": [
[
"Airi",
"Satou",
"Accountant",
"Tokyo",
"28th Nov 08",
"$162,700"
],
[
"Angelica",
"Ramos",
"Chief Executive Officer (CEO)",
"London",
"9th Oct 09",
"$1,200,000"
]
]
}
So I add ajax.dataSrc: 'data' this in datatable options. It's working good & datas are loaded.
I think dataSrc is your problem

Angular Get Data From JSON to Model And List It

I'm trying to get data from a JSON using Angular and map it to a model, then show it on a webpage.
I did it buy I'm not getting any results, like the data from JSON cannot be taken or something.
Here's my try:
The JSON:
{
"location": [
{
"_id": "5f3567a8d8e66b41d4bdfe5f",
"lat": "44.4363228",
"lng": "25.9912305",
"token": "edb153fb9d8d5628",
"__v": 0
}
]
The model:
export class Post {
public _id: string;
public token: string;
public lat: string;
public lng: string;
}
Service class:
#Injectable({ providedIn: 'root' })
export class PostsService {
public posts: Post[] = [];
private postsUpdated = new Subject<Post[]>();
Post: Promise<any>;
constructor(private http: HttpClient) {}
private url: string = 'http://localhost:8000/location';
getPosts() {
this.http
.get<{ posts: any[] }>(this.url)
.pipe(
map((postData) => {
return postData.posts.map((post) => {
console.log(this.posts);
return {
_id: post._id,
token: post.token,
lat: post.lat,
lng: post.lng,
};
});
})
)
.subscribe((transformedPosts) => {
this.posts = transformedPosts;
this.postsUpdated.next([...this.posts]);
});
}
getPostUpdateListener() {
return this.postsUpdated.asObservable();
}
}
post-list.component.ts:
#Component({
selector: 'app-post-list',
templateUrl: './post-list.component.html',
styleUrls: ['./post-list.component.css'],
})
export class PostListComponent implements OnInit, OnDestroy {
posts: Post[] = [];
private postsSub: Subscription;
result: any;
constructor(public postsService: PostsService) {
//dependency-injection
}
ngOnInit() {
this.postsService.getPosts();
this.postsSub = this.postsService
.getPostUpdateListener()
.subscribe((posts: Post[]) => {
this.posts = posts;
});
}
onShow() {
console.log('TODO');
}
ngOnDestroy() {
this.postsSub.unsubscribe();
}
}
post-list.component.html:
<mat-accordion multi="true" *ngIf="posts.length > 0">
<mat-expansion-panel *ngFor="let post of posts">
<mat-expansion-panel-header>
{{ post.token }}
</mat-expansion-panel-header>
<p>{{ post.lat }}</p>
<p>{{ post.lng }}</p>
<mat-action-row>
<button mat-raised-button color="accent" (click)="onShow(post._id)">
SHOW
</button>
</mat-action-row>
</mat-expansion-panel>
</mat-accordion>
<p class="info-text mat-body-1" *ngIf="posts.length <= 0">No posts added yet</p>
app.component.html:
<app-header></app-header> <br /><br />
<agm-map [latitude]="lat" [longitude]="lng" [zoom]="zoom">
<agm-marker [latitude]="lat" [longitude]="lng"></agm-marker>
</agm-map>
<br /><br />
<app-post-list></app-post-list>
And here's my result (photo):
I also tried to do it in different ways, always getting no result.
Any help or ideas would be much appreciated!
The error in the image says posts attribute does not exists on postData object which is gotten by get request. Absence of posts attribute is also clear in the JSON you provided.
{
"location": [
{
"_id": "5f3567a8d8e66b41d4bdfe5f",
"lat": "44.4363228",
"lng": "25.9912305",
"token": "edb153fb9d8d5628",
"__v": 0
}
]
You should completely remove the pipe and it should be fine.

Render JSON with sub object using React

Maybe someone there knows, how can I render "department" object from JSON?
[
{
"id": 1,
"name": "one",
"department": {
"id": 1,
"name": "development"
}
},
{
"id": 2,
"name": "two",
"department": {
"id": 2,
"name": "testing"
}
}
]
I am trying to display the data such that It's my render
render() {
const title =<h3>Employee</h3>;
const {Employees, isLoading} = this.state;
if (isLoading)
return(<div>Loading....</div>);
let rows=
Employees.map( employee =>
<tr key={employee.id}>
<td>{employee.id}</td>
<td>{employee.name}</td>
<td>{employee.department.name}</td>
<td><Button size="sm" color="danger" onClick={() => this.remove(employee.id)}>Delete</Button></td>
</tr>);
return {rows};
Tanx very much!
render() {
const title =<h3>Employee</h3>;
const {Employees, isLoading} = this.state;
if (isLoading)
return(<div>Loading....</div>);
let rows=
Employees.map( employee => {
return `<tr key=${employee.id}>
<td>${employee.id}</td>
<td>${employee.name}</td>
<td>${employee.department.name}</td>
<td><Button size="sm" color="danger" onClick=${() => this.remove(employee.id)}>Delete</Button></td>
</tr>` });
return {rows};
I fixed id! I needed to my back end code modify some... from "department" to private String departmentName;
and front
let rows=
Employees.map( employee =>
<tr key={employee.id}>
<td>{employee.id}</td>
<td>{employee.name}</td>
<td>{employee.department.departmentName}</td>
<td><Button size="sm" color="danger" onClick={() => this.remove(employee.id)}>Delete</Button></td>
</tr>);

Resources