Getting the name of many properties inside a json file with reactjs - json

I have a functional component that looks like this:
import React from 'react'
import PropTypes from 'prop-types'
import Styles from './searchbar.scss'
const AutoFill = (props) => {
const results = props.results || {}
return (
<ul className={Styles.searchUl}>
{Object.entries(results).map(([key, value]) => {
console.log('VALUE', value)
console.log('VALUENAME', value.apple.name)
return (
<li className={Styles.searchLi}>
<a className={Styles.searchA} href={value.apple.href} target='_blank' rel='noopener noreferrer' key={value.href}>
{value.apple.name}
</a>
</li>
)
})}
</ul>
)
}
AutoFill.propTypes = {
results: PropTypes.array
}
export default AutoFill
I also have a Json file that looks like this:
{
"results": {
"apple": {
"name": "apple",
"href": "https://www.apple.com/"
},
"armadillo": {
"name": "armadillo",
"href": "https://www.armadillo.com/"
},
"box": {
"name": "box",
"href": "https://www.box.com/"
},
"berserk": {
"name": "berserk",
"href": "https://www.berserk.com/"
}
}
}
With console.log('Resultsssssss', (results[key].apple.name)) i get the specified name of apple only which returns obv apple.
So i want to know how i can return the name of all the objects at once, To show them in a UL under a searchbar for a autoFill when typed a everything of a should appear as suggestions: https://gyazo.com/006e856190e8e063934a07eb0725926e
Any answer will be highly appreciated and looked into.

First, you want to get all the values of the object. Object.values(results) will return an array that looks like this:
[
{
"name": "apple",
"href": "https://www.apple.com/"
},
{
"name": "armadillo",
"href": "https://www.armadillo.com/"
},
{
"name": "box",
"href": "https://www.box.com/"
},
{
"name": "berserk",
"href": "https://www.berserk.com/"
}
]
Now you can use map to get the names: Object.values(results).map(x => x.name). This will return an array of names: ['apple', 'armadillo', ...].

When you passed 2 arguments in your map function, first one is general key of your json file, results in your case and second argument is content under this key.
Try this:
const AutoFill = (props) => {
const results = props.results || []
return (
Object.entries(results).map(([name, content]) => {
for (const key in content) {
if (content.hasOwnProperty(key)) {
console.log('Resultsssssss', (content[key].name))
}
}
})
)
}

You can simply return all properties within from within the map function without the for loop which you have in your code
const data = {
"results": {
"apple": {
"name": "apple",
"href": "https://www.apple.com/"
},
"armadillo": {
"name": "armadillo",
"href": "https://www.armadillo.com/"
},
"box": {
"name": "box",
"href": "https://www.box.com/"
},
"berserk": {
"name": "berserk",
"href": "https://www.berserk.com/"
}
}
}
const res = Object.entries(data.results).map(([key, value]) => {
return value.name;
});
console.log(res);
What you need for render is to restructure your HTML a little bit
const data = {
"results": {
"apple": {
"name": "apple",
"href": "https://www.apple.com/"
},
"armadillo": {
"name": "armadillo",
"href": "https://www.armadillo.com/"
},
"box": {
"name": "box",
"href": "https://www.box.com/"
},
"berserk": {
"name": "berserk",
"href": "https://www.berserk.com/"
}
}
}
const Styles = {}
const AutoFill = (props) => {
const results = props.results || {}
return (
<ul className={Styles.searchUl}>
{Object.entries(results).map(([key, value]) => {
return (
<li className={Styles.searchLi}>
<a className={Styles.searchA} href={value.href} target='_blank' rel='noopener noreferrer' key={value.href}>
{value.name}
</a>
</li>
)
})}
</ul>
)
}
ReactDOM.render(<AutoFill results={data.results} />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app" />

Related

convert JavaScript nested array for priming tree format

i have following JAVASCRIPT OBJECT and i need to convert it to primeng tree format , please help
INPUT
{
"com": {
"ups": {
"demo": {
"a": 9
}
}
}
}
OUTPUT expected
[
{
"label": "COM",
"data": "COM",
"children": [{
"label": "ABC",
"data": "abc",
"children": [ "label": "x" data": "x" ,children:[]]
}]
}]
Working Example
validate(a) {
let newArr = [];
for (const key in a) {
if (key) {
newArr.push({data: key, label: key, childern: this.validate(a[key])});
}
}
return newArr;
}
const a = {
"com": {
"ups": {
"demo": {
"a": 9
}
}
}
};
console.log(this.validate(a));

Vue.js Filtered list Method

I am still learning Vue.js. At the moment I am trying to make a simple filtered list method that pulls the data from a json file in Vue. I think that I am having trouble figuring out the correct syntax.
I just cant seem to get it right. Any help is more than welcome :)
This is Vue file:
<template>
<section>
<ul>
<li v-for="product in rings" :key="product">
{{product.title}}
</li>
</ul>
</section>
</template>
<script>
import data from '#/assets/data.json';
export default {
data() {
return {
products: []
}
},
methods: {
computed: {
rings(){
return this.products.filter(product => product.type == 'Ring')
}
}
}
}
</script>
And this is the Json file:
{ "products": [
{
"title": "Ring 1",
"description": "something",
"type": "Ring",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
},
{
"title": "Halskæde 1",
"description": "something",
"type": "Halskæde",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
},
{
"title": "Armbånd 1",
"description": "something",
"type": "Armbånd",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
},
{
"title": "Ørering 1",
"description": "something",
"type": "Ørering",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
}
]
}
You imported the data but never used anywhere inside the component:
import data from '#/assets/data.json';
// notice the data here is just a variable and it has nothing to do with the
// component's data property
export default {
data () {
return {
products: data.products // init products with imported data
}
},
Or with the destructuring syntax:
import { products } from '#/assets/data.json';
export default {
data () {
return {
products // init products with imported data
}
},

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"
}
]
}
]

Set next step for the waterfall dialogue in Microsoft BotBuilder NodeJS SDK

I am using Microsoft Bot Framework for my facebook messenger bot. I want to load the dialog data from json files instead of hard coding in the js file. I would like to configure the next step in the dialog, based on result from the "current" step, which is part of the json file configuration, something like this.
{
"name": "welcome",
"type": "waterfall",
"steps": [
{
"id": 0,
"data": [
{
"type": "text",
"value": "Hey, It's nice to meet you."
},
{
"type": "quickReplies",
"value": "What do you want to do next?",
"options": [
{
"text": "some option 1",
"value": "option1"
},
{
"text": "some option 2",
"value": "option2"
}
]
}
],
"next": [
{
"result": "option1",
"action": "goto step 2"
},
{
"result": "option2",
"action": "goto step 5"
}
]
}
]
}
I would like to process all the incoming messages and respond with correct dialog or correct step in the dialog for the user.
I am trying something like this;
handleMessage = function (session) {
var step = session.dialogData["BotBuilder.Data.WaterfallStep"] || 0;
// check response data from previou step and identify the next step.
// set the waterfall step id
session.dialogData["BotBuilder.Data.WaterfallStep"] = 2;
session.send("Hello");
}
var bot = new builder.UniversalBot(connector, function (session) {
handleMessage(session);
})
.set('storage',tableStorage);
With this code, I am always getting step as zero for session.dialogData["BotBuilder.Data.WaterfallStep"] even after setting this to a different number.
Also, as soon as I set the waterfall step number, all other state data that is stored in my table storage for this conversation is gone.
Storage data before setting waterfall step:
{
"BotBuilder.Data.SessionState": {
"callstack": [
{
"id": "*:/",
"state": {
"BotBuilder.Data.WaterfallStep": 0
}
},
{
"id": "*:welcome",
"state": {
"BotBuilder.Data.WaterfallStep": 1
}
},
{
"id": "BotBuilder:prompt-text",
"state": {
"options": {
"prompt": {
"type": "message",
"agent": "botbuilder",
"source": "facebook",
"address": {
"id": "mid.$cAAAlr-0LRH9niO21L1hV6hs83GuJ",
"channelId": "facebook",
"user": {
"id": "XXXX",
"name": "XXXX"
},
"conversation": {
"isGroup": false,
"id": "XX"
},
"bot": {
"id": "XXX",
"name": "XXX"
},
"serviceUrl": "https://facebook.botframework.com"
},
"text": "what do you want to next"
//ignored for simplicity
},
"promptAfterAction": true,
"libraryNamespace": "*"
},
"turns": 0,
"lastTurn": 1517594116372,
"isReprompt": false
}
}
],
"lastAccess": 1517594112740,
"version": 0
}
}
After I set the waterfall step:
{
"BotBuilder.Data.SessionState": {
"callstack": [
{
"id": "*:/",
"state": {
"BotBuilder.Data.WaterfallStep": 2
}
}
],
"lastAccess": 1517602122416,
"version": 0
}
}
Interestingly the step number is saved to the database (but in session state) but my "session" variable do not have this value anywhere. Also, even after configuring custom state service, the serviceUrl is still https://facebook.botframework.com which I thought is the default state service used if there is no state service set for the bot.
Per your code, as your bot actually contains only one waterfall step: handleMessage(session);, which raised your issue. You can consider to create multiple dialogs from json configration instead of complex waterfall steps.
Here is my quick test, for your information:
const json = `
[{
"name": "welcome",
"type": "waterfall",
"steps": [
{
"id": 0,
"data": [
{
"type": "text",
"value": "Hey, It's nice to meet you."
},
{
"type": "quickReplies",
"value": "What do you want to do next?",
"options": [
{
"text": "some option 1",
"value": "option1"
},
{
"text": "some option 2",
"value": "option2"
}
]
}
],
"next": [
{
"result": "option1",
"action": "dialog2"
},
{
"result": "option2",
"action": "dialog3"
}
]
}
]
},{
"name":"dialog2",
"type": "waterfall",
"steps": [
{
"data": [
{
"type": "text",
"value": "Hey, this is dialig2."
}]
}
]
},{
"name":"dialog3",
"type": "waterfall",
"steps": [
{
"data": [
{
"type": "text",
"value": "Hey, this is dialig3."
}]
}
]
}]
`;
const generateSignleStep = (step) => {
return (session, args, next) => {
step.forEach(sentence => {
switch (sentence.type) {
case 'quickReplies':
let choices = sentence.options.map(item => {
return item.value
});
let card = new builder.ThumbnailCard(session)
.text(sentence.value)
.buttons(sentence.options.map(choice => new builder.CardAction.imBack(session, choice.value, choice.text)))
let message = new builder.Message(session).addAttachment(card);
builder.Prompts.choice(session, message, choices);
break;
case 'text':
default:
session.send(sentence.value)
break;
}
})
}
}
const generatenextAction = (actions) => {
return (session, args, next) => {
const response = args.response;
actions.map(action => {
if (action.result == response.entity) {
session.beginDialog(action.action);
}
})
}
}
const generateWaterfallSteps = (steps) => {
let waterfall = [];
steps.forEach(step => {
waterfall.push(generateSignleStep(step.data));
if (step.next) {
waterfall.push(generatenextAction(step.next));
}
});
return waterfall;
}
var bot = new builder.UniversalBot(connector);
const jsonobj = JSON.parse(json);
jsonobj.forEach(dialog => {
bot.dialog(dialog.name, generateWaterfallSteps(dialog.steps))
.triggerAction({
matches: new RegExp(dialog.name, "g")
})
});
The result is:

ReactJS Display API in Component

I am new to react. I am using an api in the form of
{
"category": "dogs",
"available": [
{
"name": "pedro",
"breed": "chihuahua"
},
{
"name": "roxane"
"breed": "beagle"
}
]
},
{
"category": "cat",
"available": [
{
"name": "garfield",
"breed": "tobby"
}
]
}
I want to display ALL the pets available from the same category in name-breed pairs.
Example: Display all dogs
Pedro
Chihuahua
Roxane
Beagle
but that array is giving me hard times.
Attempt
App.jsx
{this.state.data.map((availablePets, i) => <Content key = {i} data = {Content} />)}
Content.jsx
{this.props.data.available[WhatDoIPutHere?].name}
{this.props.data.available[ajsnxnnx].breed}
Is there another way to display ALL the available pets from the same category in name-breed pairs?
SOLVED
{this.props.data.faqs.map((QA,i) =>
<div key={i}>
<h4>{this.props.data.category[i].name}</h4>
<p>{this.props.data.category[i].breed}</p>
</div>
)}
Your solution is not dynamic.
This will be a better solution.
{
this.props.data.faqs.map((QA,i) => {
const pets = QA.available.map((pets, j) => {
return <div key={j}
<h4>{pets.breed}</h4>
<p>{pets.name}</p>
</div>
})
return <div key={i}>
<h4>{QA.category}</h4>
{pets}
</div>
})
}