Render JSON with sub object using React - node.js

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>);

Related

how to map the data in table row?

I fetch channels 1,2,3,4 from get method and then call post data in which I call function parameter and check the get method data in the body parameter of post method and print the data of post method but it is in the form of object in the console and I want to store in temp and them display it in the web page.
code*
import React, { useEffect, useState } from "react";
import "./main.css"
import { AiOutlineCheck, AiOutlineClose, AiOutlineArrowUp, AiOutlineArrowDown } from "react-icons/ai";
import axios from "axios";
const Header = () => {
const [setdata, fetchdata] = useState([]);
const [setpostData, Postdata] = useState([]);
useEffect(() => {
getfetchData();
}, [])
useEffect(() => {
setdata.forEach(function (val) {
getPostData(val.Player, val.IP, val.Port, val.ChannelName);
// setInterval(() => {
// getPostData(val.Player, val.IP, val.Port, val.ChannelName);
// }, 500);
});
}, [setdata]);
function getfetchData() {
axios.get("http://localhost:9763/api/getPlayers",
{
headers: {
"accepts": "application/json",
'Access-Control-Allow-Origin': '*',
},
auth: {
username: 'admin',
password: 'password'
},
}).then(response => {
//console.log(response.data)
//console.log([...Object.values(response.data).flat()]);
fetchdata([...Object.values(response.data).flat()]);
}).catch(error => {
console.log(error);
});
}
var temp = [];
// Post Data
function getPostData(Player, IP, Port, channelName) {
var data = {
PlayerName: Player,
ChannelName: channelName,
Port: Port,
IpAddress: IP
}
axios({
method: 'post',
url: 'http://localhost:9763/api/getPlayerStatus',
data,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
auth: {
username: 'admin',
password: 'password'
}
}).then(response => {
}).catch(error => {
console.log("Error In Post Data", error);
});
}
// console.log("set", setpostData);
return (
<div className="container-fluid pt-2">
<table className=" table-borderless text-center" id="refresh">
<thead>
<tr className="title" >
{
Object.values(setdata).map((val) => {
return (
<th key={val.Player} > <AiOutlineCheck style={{ color: 'black', backgroundColor: "#41fc00", borderRadius: "25px" }} />
{val.ChannelName} </th>
)
})
}
</tr>
</thead>
<tbody>
<tr >
{
setpostData.map((val, index) => {
// console.log("Inside Map", val);
return (
<td key={index}>{val.Properties.Upcounter} </td>
)
})
}
</tr>
<tr>
{
setpostData.map((val, index) => {
// console.log("Inside Map", val);
return (
<td key={index}>{val.Properties.DownCounter} </td>
)
})
}
</tr>
</tbody>
</table>
</div >
);
}
export default Header;
Console Response.data show object
how to make this 4 object in one array so that its easily to map in row
[
{
"Status": 1000,
"Properties": {
"ClipName": "Clip1",
"Upcounter": "15:33:44:33",
"DownCounter": "16:33:44:33",
"ChannelName": "Channel1",
"StartTimeCode": "00:00:00:00",
"PlayerName": "Vtr1",
"Duration": "12:00:00:01"
}
}
]
[
{
"Status": 1000,
"Properties": {
"ClipName": "Clip3",
"Upcounter": "12:33:44:33",
"DownCounter": "12:33:44:33",
"ChannelName": "Channel3",
"StartTimeCode": "00:00:00:00",
"PlayerName": "Vtr3",
"Duration": "12:00:00:01"
}
}
]
[
{
"Status": 1000,
"Properties": {
"ClipName": "Clip1",
"Upcounter": "15:33:44:33",
"DownCounter": "16:33:44:33",
"ChannelName": "Channel1",
"StartTimeCode": "00:00:00:00",
"PlayerName": "Vtr1",
"Duration": "12:00:00:01"
}
}
]
[
{
"Status": 1000,
"Properties": {
"ClipName": "Clip1",
"Upcounter": "15:33:44:33",
"DownCounter": "16:33:44:33",
"ChannelName": "Channel1",
"StartTimeCode": "00:00:00:00",
"PlayerName": "Vtr1",
"Duration": "12:00:00:01"
}
}
]
you have to map the values before <tr> I think its work. can you post the output UI of the table
And for merging array object you can do this way. I think its work
var newArray = [...arr1, ...arr2, ...aar3,...arr4];

how to iterate over objects of objects and display in mustache template

I have the following data structure
{ 'the-subtle-art-of-not-givng-a-f': { "id: "test", "title": "test"}, "the-hamset": {"id": "test", "title": "test"}}
how can I display the title in a mustache template?
jQuery
HTML:
<div id="output">
</div>
<script type="text/template" id="titles">
<ul>
{{#titles}}
<li>{{title}}</li>
{{/titles}}
</ul>
</script>
JS:
$(document).ready(function(){
const template = $('#titles').html();
const output = $('#output');
const object = {
'the-subtle-art-of-not-givng-a-f': {
"id": "test", "title": "test1"
},
"the-hamset": {
"id": "test", "title": "test2"
}
};
let titles = [];
for (const property in object) {
if (object.hasOwnProperty(property)) {
if (object[property].title) {
titles.push( { title: object[property].title });
}
}
}
const data = { titles };
const result = Mustache.render(template, data);
output.append(result);
});
Example
Vanilla JS:
HTML:
<div id="output">
</div>
<script type="text/template" id="titles">
<ul>
{{#titles}}
<li>{{title}}</li>
{{/titles}}
</ul>
</script>
JS:
const callback = function() {
const template = document.querySelector('#titles').innerHTML;
const output = document.querySelector('#output');
const object = {
'the-subtle-art-of-not-givng-a-f': {
"id": "test", "title": "test1"
},
"the-hamset": {
"id": "test", "title": "test2"
}
};
let titles = [];
for (const property in object) {
if (object.hasOwnProperty(property)) {
if (object[property].title) {
titles.push( { title: object[property].title });
}
}
}
const data = { titles };
const result = Mustache.render(template, data);
output.innerHTML = output.innerHTML + result;
};
if (
document.readyState === "complete" ||
(document.readyState !== "loading" && !document.documentElement.doScroll)
) {
callback();
} else {
document.addEventListener("DOMContentLoaded", callback);
}
Example

How to add a key value pair on existing object created via Vue Reactivity

I already have an existing form which is dynamically created. However, I have problems with regards to adding a new set of key value pairs to the existing object. I have used the Vue Reactivity using the this.$set() method with success on the FIRST pair only.
Output
{ "traveller_1": { "gender": "c" },
"traveller_2": { "gender": "f" },
"traveller_3": { "gender": "i" }
}
Expected Output
{ "traveller_1": { "firstname": "John", "age": "23", "gender": "m" },
"traveller_2": { "firstname": "Jane", "age": "21", "gender": "f" },
"traveller_3": { "firstname": "Jade", "age": "25", "gender": "f" },
}
Fiddle https://jsfiddle.net/stda7Lwm/
View
<div class="col-md-10" id="app"> {{ travellerDetails }}
<div class="form-row" v-for="i in travellers">
<div class="form-group col-md-6" v-for="(details, index) in bookingRequiredDetails">
<label for="required-details">{{ details }}</label>
<input
type="text"
class="form-control"
#input="prop('traveller_' + i, details, $event)"
placeholder="Required Details"
/>
</div>
</div>
</div>
JS
new Vue({
el: '#app',
mounted () {
},
data () {
return {
test: { 'unit1' : { life: 30}},
travellerDetails: { },
travellers: 3,
bookingRequiredDetails: ['fullname', 'age', 'gender'],
};
},
methods: {
prop: function(obj, prop, event) {
this.$set(this.travellerDetails, obj, { [prop] : event.target.value } );
console.log(this.travellerDetails);
}
},
})
You're overriding all object every time you assign new value. You should change a single prop only
prop: function(obj, prop, event) {
const data = this.travellerDetails[obj] || {}
data[prop] = event.target.value
this.travellerDetails = {
...this.travellerDetails,
[obj]: {...data}
}
}

Having issues using axios to handle my JSON data

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 }));
}

with binding not working with default values

I have the following scanrio.
The child object defination
function SearchFilterOption(data){
var self = this
self.FilterCheck = ko.observable(false)
self.List = ko.observableArray([])
self.SelectedOptions = ko.observableArray([])
self.FilterText = ko.computed(function(){
var selectedDescriptions = [];
ko.utils.arrayForEach(self.List(), function (item) {
if (in_array(item.Value, self.SelectedOptions()))
selectedDescriptions.push(item.Description)
})
return selectedDescriptions.join(',')
})
self.FilterLabel = ko.computed(function(){
return (self.SelectedOptions() && self.SelectedOptions().length > 0) ? 'selected_filter' : ''
})
self.FilterClass = ko.computed(function(){
self.List(data)
return ( self.FilterCheck() == true ) ? 'set_check':'un_check'
})
self.Toggle = function(){
self.FilterCheck(!self.FilterCheck())
}
}
The parent model
var page = function() {
var self = this
self.LookupData = ko.observableArray()
self.Countries = ko.observableArray([])
self.LoadData = function(){
self.GetProfileData()
self.GetPreviousSearch()
}
self.GetProfileData = function(){
var url = 'ProfileApi/Index'
var type = 'GET'
var data = null
ajax(url , data , self.OnGetProfileDataComplete , type)
}
self.OnGetProfileDataComplete = function(data){
self.LookupData(getLookupData())
self.Countries(new SearchFilterOption(self.LookupData().Countries))
}
self.GetPreviousSearch = function(){
var url = 'SearchApi/PreviousSearch'
var type = 'GET'
var data = null
ajax(url , data , self.OnGetPreviousSearchComplete , type)
}
self.OnGetPreviousSearchComplete = function(data){
var search = data.Payload
if(search.locationCountryList){self.Countries().SelectedOptions(self.MakeInt(search.locationCountryList))}
}
self.MakeInt = function(array){
return array.map(function(item) {
return parseInt(item, 10);
})
}
self.LoadData()
}
And binding
$('document').ready(function () {
ko.applyBindings(new page())
})
<div data-bind="with:Countries">
<ul class="srh_fltr">
<li>
<label class="" data-bind="css:FilterLabel">Countries</label>
<p data-bind="text:FilterText"></p>
<div class="check_box">
<a class="un_check active" data-bind="css:FilterClass,click:Toggle">
<img src="../images/spacer.gif">
</a>
</div>
</li>
</ul>
<section class="form_view" data-bind="visible:FilterCheck">
<select multiple="multiple" data-bind="
options:List,
optionsText:"Description",
optionsValue:"Value",
optionsCaption:"--- ",
value:0,
selectedOptions:SelectedOptions"></select>
</section>
</div>
Here is some lookup data sample
[{
"Value": 1,
"Description": "United States"
}, {
"Value": 2,
"Description": "Canada"
}, {
"Value": 3,
"Description": "United Kingdom"
}, {
"Value": 4,
"Description": "Pakistan"
}, {
"Value": 5,
"Description": "India"
}, {
"Value": 6,
"Description": "Saudi Arabia"
}, {
"Value": 7,
"Description": "U.A.E."
}, {
"Value": 8,
"Description": "Afghanistan"
}, {
"Value": 9,
"Description": "Albania"
}]
OK. Code is complete. The problem is that when GetPreviousSearch is called and self.Countries().SelectedOptions() is filled nothing is selected. I mean FilterText is not displayed. i have seen in console the object contains the data filled by GetPreviousSearch but ui does not get changed? How can i resolve this issue. I suspect with biding may have to do something with it.
Here is the fiddle.
I have resolved the issue the problem is here
<select multiple="multiple" data-bind="
options:List,
optionsText:"Description",
optionsValue:"Value",
optionsCaption:"--- ",
value:0,
selectedOptions:SelectedOptions"></select>
</section>
In this i have to remove value attribute for multiselect. I found that value produces problem if used with selectedOptions in multiselect. Although if selectedOptions is used with dropdown it does not make any problem.

Resources