Take elements from Json to input in Picker - json

I'm new in react native. I'm trying to fecth a webservice and input some element from response to a Picker (I use native-base). My problem is I don't know how to take an element (here it's LIBELLE) what I need in my Json.
see the code :
getSurfaces(){
fetch('yourWebservice')
.then((response) => response.text())
.then((responseText) => {
parseString(responseText, function (err, result) {
responseText = result;
});
console.log(JSON.stringify(responseText));
this.setState({
surfaces: responseText.Surfaces.surface
}).catch(err => console.log(err));
console.log(this.state.surfaces);
}
})
.catch((err) => {
console.log('Error fetching the feed: ', err)
})
}
componentDidMount(){
this.getSurfaces();
}
My constructor:
constructor (){
super();
this.state = {
date: '',
surface: '',
surfaces: [],
start: '',
hours : [],
};
this.valueChangeSurface = this.valueChangeSurface.bind(this);
}
valueChangeSurface(value: String){
this.setState({
surface: value
});
}
My renderSurfaces method:
renderSurface(){
if(this.state.surfaces){
return this.state.surfaces.map((surface) => {
return <Picker.Item label={surface.LIBELLE} value={surface}/>
})
}
}
The render of Picker:
<ListItem>
<Left>
<Text>Surface</Text>
</Left>
<Body>
<Picker
note
inlineLabel={true}
mode={"dropdown"}
style={{width: 175}}
selectedValue={this.state.surface}
onValueChange={this.valueChangeSurface}>
{
this.renderSurface()
}
</Picker>
</Body>
<Right/>
</ListItem>
The error returned by this.setStatein getSurfaces():
Error fetching the feed: [TypeError: undefined is not an object (evaluating '_this2.setState({
surfaces: responseText.Surfaces.surface
}).catch')]
I don't really know if I take the good way to do this, I would really appreciate your help

JSON.stringify() turns a JS object to a json string. And also, you dont need of interacting over the object to set the state.
this.setState({
surfaces: responseText.Surfaces.surface;
});
You've already the surface has an JS Object.
In your code you are interacting over a JSON string object when you are rendering the component, and giving to the result the last JSON object,
{"ID":["4"],"LIBELLE":["Quicks"],"CODE":["QUICKS"],"ORDRE":["4"]}
into a JSON String object,
'{"ID":["4"],"LIBELLE":["Quicks"],"CODE":["QUICKS"],"ORDRE":["4"]}'
Before rendering the component, you can render surfaces e.g.
renderSurfaces() {
if (this.state.surfaces) {
return this.state.surfaces.map((surface) => {
return (
<Text>
{surface.LIBELLE}
</Text>
);
});
}
}

I finally find a solution :
The problem it was simple and the most part of it come from a syntaxe erreur, I replace :
responseText.Surfaces.surface.LIBELLE
by this :
responseText.Surfaces.surface[i].LIBELLE
See the entire code of getSurfaces():
getSurfaces(){ // Input the surfaces values (ID and LIBELLE) who come from WebService in the this.state.surfaces
fetch('url')
.then((response) => response.text())
.then((responseText) => {
parseString(responseText, function (err, result) {
responseText = result;
});
let sf = []; // Create a table who gonna content the value of this.state.surfaces
for(i = 0; i<responseText.Surfaces.surface.length; i++){
sf.push(responseText.Surfaces.surface[i].LIBELLE.toString());
}
this.setState({
surfaces: sf //inject the table sf who contain the table surfaces
});
})
.catch((err) => {
console.log('Error fetching the feed: ', err)
})
}

You have to provide an object for your Picker. Now you're converting your object to a string, use this instead:
surfaces.forEach(result => {
this.setState({
surfaces: result
});
console.log(this.state.surfaces);
}
The surfaces.forEach(e => {}) is the same as your loop there just a little bit simpler. Keep in mind that you don't need to use can use this kind of loops (forEach, map) almost always in JS.
If this doesn't help, please post the html snippet of you Picker.

Related

TypeError: Converting circular structure to JSON for mongodb/mongoose

var express = require("express")
let PersonModel = require('./PersonModel')
let mongodbConnected=require('./MongodbConnect')
var app =express()
var bodyparser=require("body-parser")
const { format } = require("path")
const { count } = require("console")
const { countDocuments } = require("./PersonModel")
const { exec } = require("child_process")
const { get } = require("http")
const { ALL } = require("dns")
app.use(bodyparser.urlencoded({extended:false}))
app.get('/',function(req,res){
res.sendFile('Person.html', { root: __dirname });
})
app.get('/about',function (req,res){
res.send("This is a simple express application using mongodb express html and mongoose")
PersonModel.countDocuments().exec()
.then(count=>{
console.log("Total documents Count before addition :", count)
}) .catch(err => {
console.error(err)
})
})
app.post('/add', function(req,res){
Pname=req.body.empname
console.log('Pname',Pname)
PAge=req.body.Age
PGender=req.body.gender
PSalary=req.body.salary
const doc1 = new PersonModel(
{
name:Pname,age:33,Gender:PGender,Salary
:PSalary}
)
doc1.save(function(err,doc){
if (err) return console.error(err)
else
console.log("doc is added ",doc)
//res.send("Record is added"+doc)
res.send({
'status':true,
'Status_Code':200,
'requested at': req.localtime,
'requrl':req.url,
'request Method':req.method,
'RecordAdded':doc});
}
)
})
app.post('/findperson', function(req,res){
PAge=req.body.Age
console.log("Page",PAge)
PersonModel.find({age:{$gte:PAge}})
// find all users
.sort({Salary: 1}) // sort ascending by firstName
.select('name Salary age')// Name and salary only
.limit(10) // limit to 10 items
.exec() // execute the query
.then(docs => {
console.log("Retrieving records ",docs)
res.send(docs)
})
.catch(err => {
console.error(err)})
})
app.post('/delete', function(req,res){
Pgender=req.body.gender
PersonModel.findOneAndDelete({Gender:Pgender }
).exec()
.then(docs=>{
console.log("Deleted")
console.log(docs); // Success
}).catch(function(error){
console.log(error); // Failure
});
})
app.post('/update', function(req,res){
Pname=req.body.empname
Pnewname=req.body.newname
PnewAge=req.body.newage
PersonModel.findOneAndUpdate({ name: Pname },{"$set":{name:Pnewname,age:PnewAge}}).exec()
.then(docs=>{
console.log("Update for what i get is ",Pname
,Pnewname,PnewAge)
console.log(docs); // Success
}).catch(function(error){
console.log(error); // Failure
});
})
var docnum=PersonModel.countDocuments(ALL)
app.post('/count', function(req, res){
res.send('Total number of documents: ', docnum)
})
app.listen(5000,function(){
console.log("Server is running on the port 5000")
})
Hello.
First time posting on stackoverflow, dont know what kind of information to post, please let me know.
Im trying to make a page (/count) to simply display the number of documents. I've tried different code but nothing is working. This error keeps coming up "TypeError: Converting circular structure to JSON".
This is school work so the code is given to me by a teacher and I have to add a POST method to add a page that displays total number of documents.
Any ideas?
Thanks.
Circular structure is not about mongo but how JS read the JSON object.
For example, if you have this object:
var object = {
propA: "propA",
propB: object
}
When JS try to deserialize JSON object, will handle that: One object contains the object that contain again the object and again and again... that is a circular dependence.
Not only with one object itself, aslo with more objects:
var objectA = {
propA: objectB
}
var objectB = {
propA: objectA
}
Is the same case.
Using node.js you can use util.inspecet() which automatically show [Circular] when a circular dependence is found.
You can use like this:
var util = require('util')
console.log(util.inspect(objectA))

Can not map over a response json array

I have the Json response from an api in the below format
[
{
id: 1,
class: '10',
section: 'A',
subject: 'Social'
},
{
id: 2,
class: '8',
section: 'C',
subject: 'Social'
},
{
id: 3,
class: '9',
section: 'A',
subject: 'Social'
}
]
I am storing the json response in a state variable and able to print the above json array successfully.
async ListAllTodaysClasses() {
try {
let data = new FormData();
data.append('id', this.state.id)
data.append('year',this.state.year)
data.append('month',this.state.month)
data.append('day', this.state.day)
var url = this.state.url;
console.log(url);
let response = await fetch(url, {
method: 'POST',
body: data
});
let res = await response.json();
this.setState({
subjects: res
})
console.log(this.state.subjects)
} catch(error) {
this.setState({error: error});
console.log("error " + error);
}
}
Here I am trying to loop over an json response array.
this.state.subjects.map((item, key) => (
<TouchableOpacity key={key}>
<View>
{
<Text style={styles.textColor2}>{item.class}th-{item.section}/ {item.subject}</Text>
}
</View>
</TouchableOpacity>
))
But I am getting Typeerror: undefined is not a function
Your question has nothing to do with JSON. You're storing the result of calling response.json(), which parses the JSON in the response and returns the parsed result.
Your code to store it is correct:
this.setState({
subjects: res
})
so I suspect the problem is in your constructor where you set your initial state. The correct initial state for subjects would be like this:
// In your constructor
this.state = {
/*...any other state you have...*/,
subjects: []
};
Notice that subjects is an empty array. I suspect you're setting it to {} (an empty object) or "" (an empty string) or similar. (You're clearly not failing to initialize it, and not using null, since that would produce a different error.)
Side note: Although your setState call is correct, what follows it is not:
this.setState({
subjects: res
})
console.log(this.state.subjects) // <=== Will not see the updated state
Remember that state updates are asynchronous.
You probably need to init your state.subjects:
class YourClassName extends React.Component {
constructor() {
this.state = {
subjects: []
}
}
}

Calling a local json file and parsing data in ReactJS

I have the following json file. Right now, i have kept this in my ReactJS project itself locally. Later on planning to move in a server location.
abtestconfig.json
[
{
"abtestname": "expAButton",
"traffic": 1,
"slices":
[
"orange",
"blue"
]
},
{
"abtestname": "expTextArea",
"traffic": 0.5,
"slices":
[
"lightgrey",
"yellow"
]
}
]
I want to read and get data and parse it and apply in a function. I got some reference sample code and trying to use fetch api to react json file with the following code.
After reading this json file, i will have to pass the data in abtest function, as you can see now it's sending with hard coded value abtest('expAButton', 0.75).slices('orange', 'blue').run(function ()
I have the following doubts and wanted to get your guidance / clarification.
1. Is it correct way to read json file using fetch api? Is there any other best approach?
2. When I use fetch api like mentioned below, console log displays GET http://localhost:8080/abtesting/abtestconfig.json 404 (Not Found)
app.jsx file:
import './abtesting/abtestconfig.json';
class App extends React.Component {
constructor() {
super();
this.onClick = this.handleClick.bind(this);
this.onClickNewUser = this.handleNewUser.bind(this);
this.state = {
bgColor: '',
data: []
}
};
handleNewUser (event) {
abtest.clear();
window.location.reload();
}
render() {
return (
<Helmet
/>
<p><b>A/B Testing Experience</b></p>
<div className="DottedBox">
<p><button id = "newUserButton" onClick = {this.onClickNewUser} style={{backgroundColor:"red"}}>Welcome and click here</button></p>
</div>
);
}
handleClick () {
abtest('expAButton', 0.75).slices('orange', 'blue').run(function () {
expAButton.style.backgroundColor = this.slice.name;
});
}
setStyle (stylecolor) {
this.setState({
bgColor: stylecolor
})
}
componentDidMount () {
this.handleClick();
fetch('./abtesting/abtestconfig.json').then(response => {
console.log(response);
return response.json();
}).then(data => {
// Work with JSON data here
console.log(data);
}).catch(err => {
// Do something for an error here
console.log("Error Reading data " + err);
});
}
}
export default hot(module)(App);

TypeError: obj[key].includes is not a function

This is the request (Updated):
this._service.getPeople().subscribe((response) => {
this.people = response;
});
This is the method:
filterIt(arr: any, searchKey: any) {
return arr.filter((obj: any) => {
return Object.keys(obj).some((key) => {
return obj[key].includes(searchKey);
});
});
}
The result that I want is to filter the table rows, but what I get is:
TypeError: obj[key].includes is not a function
A must know is that this code works perfectly with an array of objects hardcoded, but when I get the data from the backend using a service (http.get), the service works fine and returns a JSON with the dat but I'm still geting the error. Any help would be appreciated!
I am working with Typescript 2.7.2, Angular 6 and MDBootstrap 6.2.2(Angular).
I just found the answer by my self, the thing is that I had one of the properties null, that was what rising the error, so I just transformed the method below and it'works like charm! I hope this helps somebody.
filterIt(arr: any, searchKey: any) {
return arr.filter((obj: any) => {
return Object.keys(obj).some((key) => {
if (obj[key] !== null) {
const tempKey = obj[key].toString().toLowerCase();
const tempSearch = searchKey.toLowerCase();
return tempKey.includes(tempSearch);
}
});
});
}

React/Redux - Issue iterating json from mapStateToProps

I have a React Native app on which I'm trying to apply Redux. It's the first time I try to use Redux, so I think I'm not seeing the elephant in the room.
The problem is that I can't access my props data (generated with mapStateToProps). Here's my code:
reducer.js (in the console log I see the json objects just fine)
const INITIAL_STATE = {
etiquetas: []
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case FETCH_ETIQUETAS_SUCCESS:
//console.log("payload: "+action.payload);
return { ...state, etiquetas: action.payload };
default:
return state;
}
};
component.js (in the console.log I see my data, BUT it seems that it's all in one object now, this is probably what I'm not seeing).
class EtiquetasList extends Component {
componentDidMount() {
this.props.FetchEtiquetas();
}
renderEtiquetas() {
//console.log("etq: "+JSON.stringify(this.props.etiquetas));
if ( this.props.etiquetas.length == 0 ) {
return <ActivityIndicator size="large" color="#00ff00" />
} else {
return this.props.map(etiqueta =>
<EtiquetaDetail key={etiqueta.id} etiqueta={etiqueta} />
);
}
}
render() {
return (
<ScrollView>
{this.renderEtiquetas()}
</ScrollView>
);
}
}
const mapStateToProps = (state) => {
return {
etiquetas: state.etiquetas
};
};
export default connect(mapStateToProps, { FetchEtiquetas })(EtiquetasList);
The map function is for Arrays, not Objects, I know. That's part of my old code.
action.js
import axios from 'axios';
import { FETCH_ETIQUETAS, FETCH_ETIQUETAS_SUCCESS, FETCH_ETIQUETAS_FAILURE } from './types';
const url= 'https://e.dgyd.com.ar/wp-json/wp/v2/etiquetas?_embed&per_page=7';
const fetchSuccess = (dispatch, data)=> {
dispatch({
type: FETCH_ETIQUETAS_SUCCESS,
payload: data
});
}
export function FetchEtiquetas() {
return function (dispatch) {
axios.get( url )
.then(response => {
dispatch({ type: FETCH_ETIQUETAS_SUCCESS, payload: response.data })
} );
}
}
reducers/index.js
import { combineReducers } from 'redux';
import DataReducer from './DataReducer';
export default combineReducers({
etiquetas: DataReducer
});
So, my questions are:
Why is is this always returning undefined?
this.props.etiquetas.length == 0
Why mapStateToProps seems to convert my array of objects into a single object? is this why I have to use JSON.stringify in the console log?
and finally, how do I access my data in the component?
Thank you much in advance!
The problem here, is just the way that you structured your reducer.
const INITIAL_STATE = {
etiquetas: []
};
The code above means that you are creating an object, with a property named "etiquetas" that holds an empty array initially.
In your root reducer file, you import that object, and assign it the name, "etiquetas". So really what your reducer is returning is this:
etiquetas: {
etiquetas: [your array of data]
}
This would explain why you complained about receiving an object. There are two ways to rectify this,
One: Change the mapStateToProps function to this,
const mapStateToProps = (state) => {
return {
etiquetas: state.etiquetas.etiquetas
};
};
Two: Change your reducer to look like this,
export default (state = [], action) => {
switch (action.type) {
case FETCH_ETIQUETAS_SUCCESS:
//console.log("payload: "+action.payload);
return action.payload;
default:
return state;
}
};
This will make sure your reducer returns just an array, not an object with an array inside of it stored in a property. Its up to you to decide which you like better.