How to make dynamic Sidebar from Json api? - json

I am trying to create a React Dynamic Sidebar from the Json API.
I need a coding assist for double iteration in React by using below three conditions:
if json element id === 0 ===> outer 1st level Mennuitem
if json element[i] id ===[j] parent_id ===> 2nd level submenu item
if parent_id[i]===[j] id && [j]parent_id===0 ===>3rd level submenuitem
But I can achieve outer MenuItem. But I fail to create SubMenuItem.
Please help me to fix this issue. Please see the attached image. Thanks
class App extends Component {
constructor(props) {
super(props);
this.state = {
mz:[
{
"id": 1,
"name": "Menu1",
"parent_id": 0
},
{
"id": 9,
"name": "SubMenu1-Menu1",
"parent_id": 1
},
{
"id": 26,
"name": "8989",
"parent_id": 9
},
{
"id": 10,
"name": "SubMenu2-Menu1",
"parent_id": 1
},
{
"id": 2,
"name": "Menu2",
"parent_id": 0
},
{
"id": 11,
"name": "SubMenu1-Menu2",
"url": "",
"order": 210,
"type": 3,
"is_active": true,
"parent_id": 2
},
{
"id": 12,
"name": "SubMenu2-Menu2",
"url": "",
"order": 220,
"type": 3,
"is_active": true,
"parent_id": 2
}],};
}
render() {
return (
<div>
{this.state.api.filter((el) => (el.parent_id === 0 ? el.name : null)).map((el) => (
<ReactBootStrap.Navbar >
{el.name}
<ReactBootStrap.NavDropdown>
{(el.parent_id === el.id ? el.name : null).map((el) =>el.name)}//I CANNOT ITERATE CORRECTLY THIS PART
</ReactBootStrap.NavDropdown>
</ReactBootStrap.Navbar>
))}
</div>
);
}
}
export default App;

see this map:
this.state.mz.map(item => {
if(item.parent_id === 0){
output[item.id] = item
} else {
if(!output[item.parent_id]['submenu']){
output[item.parent_id]['submenu'] = {}
}
output[item.parent_id]['submenu'][item.id] = item
}
})

Related

Show product.length when I have JSON / OBJ / JSON / OBJ / JSON

I have this JSON
{
"StatusCode": 0,
"StatusMessage": "OK",
"StatusDescription": [
{
"_id": "12123",
"dateCreated": "2019-12-03T13:45:30.418Z",
"pharmacy_id": "011E752345553380ABC13FFA163ECD15"
"products": [
{
"productID": "1",
"quantity": 3,
"product_name": "BETADINE",
"price": 10
},
{
"productID": "2",
"quantity": 1,
"product_name": "EUCARBON",
"price": 10
}
]
},
{
"_id": "56233",
"dateCreated": "2019-12-04T09:55:21.555Z",
"pharmacy_id": "011E762345552280FBC13FFA163ECD10"
"products": [
{
"productID": "44",
"quantity": 1,
"product_name": "BETADINE",
"price": 10
}
]
}
]
}
In this JOSN I want to get length of products. For example in this I have 2 pharmacy and 5 products. I want to show 5 in my shop cart.
So I get this JSON from API with this function:
public cart: Shop[];
cartlength: number;
ngOnInit(): void {
this.shopservice.getShoppingCart().subscribe(
cart => {
this.cart = cart;
this.cartlength = cart.length;
},
err => console.error('errorrrrrrr', err),
() => console.log('error')
);
}
IN HTML:
<ActionItem ios.systemIcon="9" ios.position="left" android.position="actionBar" [text]='cartlength'></ActionItem>
Any idea please?
If cart is the array containing all the pharmacies you could use reduce method to determine the total quantity of all products for each pharmacy.
this.cartlength = this.cart.reduce((count, pharmacy) => {
count += pharmacy.products.reduce((totalQty, product) => {
return totalQty += product.quantity;
}, 0)
return count;
}, 0)

How to dynamically add object inside json array?

I'm trying to dynamically add an object inside every object which is present in my json array. But I'm unable to do so. My object is getting appended at the end of json which is not what I want.
jsonArray:any=[
{
"id": 1000,
"body": "some comment",
"postId": 1
},
{
"id": 2,
"body": "some comment",
"postId": 1
},
{
"id": 3,
"body": "some comment",
"postId": 1
}
]
selectFLag:any={"selected":"true"}
temArray:any;
learnJSONPArse()
{
for (var i = 0; this.jsonArray.length > i; i++)
{
Alert(this.jsonArray.length)
}
}
this.jsonArray.push(this.selectFLag)
-----expected output is
[
{
"id": 1000,
"body": "some comment",
"postId": 1,
"selected":"true"
},
{
"id": 2,
"body": "some comment",
"postId": 1,
"selected":"true"
},
{
"id": 3,
"body": "some comment",
"postId": 1,
"selected":"true"
}
]
You're question is a little unclear, but it sounds like you want to map each item in your array to a new item. The new item is the same as the old one, but assigned an additional property.
If so, something like this could work for you:
const objToAppend = { selected: true };
jsonArray.map(item => Object.assign(item, objToAppend));
Refs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Normalizr usage for deep nested obj

I am trying to use Normalizr for normalize and denormalize object that I am using within my angular ngrx app.
I found almost the solution for it here:https://www.snip2code.com/Snippet/1028240/Deep-nested-tree-normalize-with-normaliz
import {normalize, Schema, arrayOf} from 'normalizr';
var data = [
{
"id": 1,
"name": "О компании",
"children": [
{
"id": 5,
"name": "Руководство",
"children": [
{
"id": 6,
"name": "Генеральный директор",
"children": [
{
"id": 20,
"name": "Зам гендира"
},
{
"id": 8,
"name": "Секретарша"
}
]
},
{
"id": 7,
"name": "Главный бухгалтер",
"children": [
{
"id": 21,
"name": "Зам главбуха"
}
]
}
]
}
]
},
{
"id": 2,
"name": "Вакансии",
"children": [
{
"id": 9,
"name": "Фронтенд-разработчик (JS)"
},
{
"id": 10,
"name": "Бэкэнд-разработчик (Java)"
},
{
"id": 11,
"name": "Оператор ЭВМ"
}
]
}
];
The thing is that many functions from solution below changed and it is little bit hard for me to use same solution with newer release of normalizr. Maybe some of you know how to rewrite below solution into new normalizr?
var node = new Schema('nodes');
node.define({
children: arrayOf(node)
});
var treeSchema = arrayOf(node);
var normalizedData = normalize(data, treeSchema);
console.log(normalizedData);
You're looking at an example using an outdated version of Normalizr. Try reading the docs for new APIs
I did it :)
const node = new schema.Entity('nodes');
node.define({
children: [node]
})
const treeSchema = [node];
const normalizedData = normalize(this.form,treeSchema);

Fetching json data in react shows TypeError

I have some problem with fetching json data in my quiz app.
I have stored the json file in the same directory as App.js and Running.js
I want to show questions and the options for a correct answer.
All of it is stored in quiz.json file.
Running.js file:
import React,{Component} from 'react';
import {Collection,CollectionItem} from 'react-materialize';
class Running extends Component{
constructor(props){
super(props);
this.state={ques:1,score:0,isLoaded:false,items:[]};
}
componentDidMount() {
fetch("quiz.json")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result.conversations
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render(){
console.log(this.state.items);
if(this.state.isLoaded){
return (
<div>
<h1 class="header center teal-text text-lighten-2">React Quiz</h1>
<br />
<Collection header={this.state.items[0]["question"]} >
{
this.state.items[0]["answers"].map(ans =>(<CollectionItem href='#'>{ans.value}</CollectionItem>))
}
</Collection>
</div>
)
}
else{
return <div>Not Rendered</div>
}
}
}
export default Running;
The error message looks like this
TypeError: this.state.items is undefined
render
src/Running.js:37
34 | <div>
35 | <h1 class="header center teal-text text-lighten-2">React Quiz</h1>
36 | <br />
> 37 | <Collection header={this.state.items[0]["question"]} >
38 | {
39 | this.state.items[0]["answers"].map(ans =>(<CollectionItem href='#'>{ans.value}</CollectionItem>))
40 | }
the json file looks like this :
[
{
"question": "How can you access the state of a component from inside of a member function?",
"no": 1,
"answers": [
{
"key": 1,
"value": "this.getState()"
},
{
"key": 2,
"value": "this.prototype.stateValue"
},
{
"key": 3,
"value": "this.state"
},
{
"key": 4,
"value": "this.values"
}
]
},
{
"question": "Inline styling in React can be done as:",
"no": 2,
"answers": [
{
"key": 1,
"value": "style:{{}}"
},
{
"key": 2,
"value": "style:{}"
},
{
"key": 3,
"value": "style:''"
},
{
"key": 4,
"value": "All"
}
]
},
{
"question": "For classless component we use?",
"no": 3,
"answers": [
{
"key": 1,
"value": "functions"
},
{
"key": 2,
"value": "classes"
},
{
"key": 3,
"value": "JSX"
},
{
"key": 4,
"value": "None"
}
]
}
]

How to get response (array of json) and put it in my html component in Angular 4

I am trying to get the array data in a JSON response. The following is my JSON response and I need to get all data to my html tags in component.
{
data : {
"topLikedMedia" : [
{
"id": "1546567845943506613_3718981156",
"type": "image",
"user": {
"id": "3718981156",
"username": "agoramonitor",
"full_name": "AgoraMonitor",
"profile_picture": "https://scontent.cdninstagram.com/t51.2885-19/s150x150/18809269_476795959342067_7353566623065702400_n.jpg"
},
"tags": [
"instagramers",
"content",
"socialmedia",
"marketing",
"branding",
"instagram"
],
"location": null,
"comments": {
"count": 2
},
"formatted_comments_count": "2",
"created_time": "1498585275",
"formatted_time": "Tue, Jun 27, 2017 7:41 PM",
"diff_humans_time": "4 months ago",
"link": "https://www.instagram.com/p/BV2g0MGgPa1/",
"likes": {
"count": 154
},
"formatted_likes_count": "154",
"images": {
"thumbnail": {
"width": 150,
"height": 150,
"url": "https://scontent.cdninstagram.com/t51.2885-15/s150x150/e35/c244.0.591.591/19533988_862713503881059_8677706625265434624_n.jpg"
},
"low_resolution": {
"width": 320,
"height": 175,
"url": "https://scontent.cdninstagram.com/t51.2885-15/s320x320/e35/19533988_862713503881059_8677706625265434624_n.jpg"
},
"standard_resolution": {
"width": 640,
"height": 350,
"url": "https://scontent.cdninstagram.com/t51.2885-15/s640x640/sh0.08/e35/19533988_862713503881059_8677706625265434624_n.jpg"
}
},
"caption": "Whether you want to drive leads to your homepage or encourage customer engagement ",
"userHasLiked": false,
"filter": "Normal"
}
],
}
I have the temp of this output and I need to receive this response and distribute it on its own tags and i dont know how
First solution, the Angular way :
getTopLiked() {
this._dashboardService.getTopPosts()
.subscribe(res => {
// Get your data in your component's variable
this.data = res.json();
});
}
In your HTML
<div *ngIf="data">
<div *ngFor="let liked of data.topLikedMedia">
<p>ID : {{liked.id}}</p>
<!-- And you do every other field like that -->
</div>
</div>
Second solution, the old Javascript way
getTopLiked() {
this._dashboardService.getTopPosts()
.subscribe(res => {
this.createMarkup(res.json());
});
}
createMarkup(data: Object) {
this.markup = '';
for (let liked of data.topLikedMedia) {
this.markup += `<p>ID : ${liked.id}</p>`;
// add the other fields like that
}
}
In your HTML
<div *ngIf="markup">
<div [innerHTML]="markup"></div>
</div>