1

I am trying to do something simple where I have an object containing data. I am trying to take the values from that object and assign it to another object that I am going to use downstream.

I have tried several ways to set the values

 async componentDidMount () {
 try {
   const array = [

    {
      expanded: false, category_Name: "Mobiles", sub_Category: [{ 
 id: 1, name: 'Mi' }, { id: 2, name: 'RealMe' }, { id: 3, name: 
 'Samsung' }, { id: 4, name: 'Infinix' }]
  },
  {
    expanded: false, category_Name: "Laptops", sub_Category: [{ id: 
    8, name: 'Dell' }, { id: 9, name: 'MAC' }, { id: 10, name: 'HP' 
   }, { id: 11, name: 'ASUS' }]
  }
  ];

  const graphqldata =  await 
  API.graphql(graphqlOperation(listTodos))

  console.log('graphqldata:', graphqldata)

  this.setState({ AccordionData: array}, () => {});
  this.setState({ todos: graphqldata.data.listTodos.items })
  const items = this.state.todos.map((item, key) =>
  console.log("printing just name", item.name)
  var singleAccordion = new Object()
  singleAccordion.category_Name=item.name
  singleAccordion.expanded=falise
  singleAccordion.sub_Category=[{1,item.date},{2,item.location}, 
  {3,item.organizer}]
  console.log("AND PRINTING singleAccordion", singleAccordion)
  )
  console.log('AccordionData:', this.state.AccordionData)
  } catch (err) {
  console.log('error fetching data: ', err)
  }
  }`

I expect the values in the "item" object to get assigned in the singleAccordian object the way I am trying to transform one from the other. But I am getting an error: 189 | const items = this.state.todos.map((item, key) => 190 | console.log("printing just name", item.name)

191 | var singleAccordion = new Object() | ^ 192 | singleAccordion.category_Name=item.name 193 | 194 | console.log("AND PRINTING singleAccordion", singleAccordion)

1
  • Which text editor are you using? Commented Aug 22, 2019 at 2:38

1 Answer 1

1

Your code doesn't explain the main problem, I see some errors in that piece of code, I can't write a precise answer but I can help you to decrease your errors:

Indentation is important:

async componentDidMount() {
  try {
    const array = [
      {
        expanded: false,
        category_Name: "Mobiles",
        sub_Category: [
          { id: 1, name: 'Mi' },
          { id: 2, name: 'RealMe' },
          { id: 3, name: 'Samsung' },
          { id: 4, name: 'Infinix' },
        ],
      },
      {
        expanded: false,
        category_Name: "Laptops",
        sub_Category: [
          { id: 8, name: 'Dell' },
          { id: 9, name: 'MAC' },
          { id: 10, name: 'HP' },
          { id: 11, name: 'ASUS' },
        ],
      }
    ];
    // What listTodos mean?
    const graphqldata = await API.graphql(graphqlOperation(listTodos));

    console.log('graphqldata:', graphqldata)
    //  Unnecesary
    // this.setState({ AccordionData: array });

    // You need to pass a function to run after the state changes
    this.setState({
      AccordionData: array,
      todos: graphqldata.data.listTodos.items,
    }, () => {
      this.state.todos.map((item) => { // You forgot to wrap your map function
        console.log("printing just name", item.name)
        const singleAccordion = {}; // Better than new Object()
        singleAccordion.category_Name = item.name;
        singleAccordion.expanded = false;
        singleAccordion.sub_Category = [
          { id: 1, name: item.date },
          { id: 2, name: item.location },
          { id: 3, name: item.organizer },
        ];
        console.log("AND PRINTING singleAccordion", singleAccordion)
      });
    })
    // This isn't available till state has changed
    console.log('AccordionData:', this.state.AccordionData)
  } catch (err) {
    console.log('error fetching data: ', err)
  }
}

Hope it helps.

EDIT by question OP: Here's the rest of code and the render method:

 class AboutScreen extends React.Component {
 render(){
  return(
    <View style={styles.Panel_Holder}>
    <Text style={styles.category_Text}>About Screen </Text>
    <Text style={styles.sub_Category_Textt}>Put a mission statement 
    </Text>
   <Button
      title="Go to Home"
      onPress={() => this.props.navigation.navigate('Home')}
   />
   </View>

  )
 }
 }

  class Expandable_ListView extends Component {

  constructor() {

  super();

  this.state = {

  layout_Height: 0

  }
  }

 componentWillReceiveProps(nextProps) {
  if (nextProps.item.expanded) {
     this.setState(() => {
     return {
      layout_Height: null
     }
   });
  }
  else {
    this.setState(() => {
      return {
        layout_Height: 0
      }
      });
   }
   }

   shouldComponentUpdate(nextProps, nextState) {
   if (this.state.layout_Height !== nextState.layout_Height) {
     return true;
   }
   return false;
  }

  show_Selected_Category = (item) => {
  Alert.alert(item);

  }

 render() {
 return (
  <View style={styles.Panel_Holder}>

    <TouchableOpacity activeOpacity={0.8} onPress= . 
    {this.props.onClickFunction} style={styles.category_View}>

      <Text style={styles.category_Text}> . 
     {this.props.item.category_Name} </Text>

      <Image
        source={{ uri: 'https://reactnativecode.com/wp- 
        content/uploads/2019/02/arrow_right_icon.png' }}
        style={styles.iconStyle} />

    </TouchableOpacity>

    <View style={{ height: this.state.layout_Height, overflow: 
    'hidden' }}>

      {
        this.props.item.sub_Category.map((item, key) => (

          <TouchableOpacity key={key} style= . 
       {styles.sub_Category_Text} onPress= . 
       {this.show_Selected_Category.bind(this, item.name)}>

            <Text> {item.name} </Text>

            <View style={{ width: '100%', height: 1, backgroundColor: 
          '#000' }} />

          </TouchableOpacity>

        ))
       }

      </View>

    </View>

   );
  }
  }

  class HomeScreen extends React.PureComponent {

   state = { isloading: true, name: '', date: '', location: '', 
   organizer: '', sections:'', link:'', description:'', todos: [], 
   AccordionData: [], AccordianPlus:[] }


   async componentDidMount () {
   try {
     const array = [

    {
      expanded: false, category_Name: "Mobiles", sub_Category: [{ id: 
     1, name: 'Mi' }, { id: 2, name: 'RealMe' }, { id: 3, name: 
    'Samsung' },
    { id: 4, name: 'Infinix' }, { id: 5, name: 'Oppo' }, { id: 6, 
    name: 'Apple' }, { id: 7, name: 'Honor' }]
    }
    ];

   const graphqldata =  await 
       API.graphql(graphqlOperation(listTodos))

   console.log('graphqldata:', graphqldata)

   this.setState({
    isloading: false,
    AccordionData: [],
    AccordianPlus: [],
    todos: graphqldata.data.listTodos.items,
    }, () => {
     this.state.todos.map((item) => { // You forgot to wrap your map 
    function
    console.log("printing just name", item.name)
    const singleAccordion = {}; // Better than new Object()
    singleAccordion.category_Name = item.name;
    singleAccordion.expanded = false;
    singleAccordion.sub_Category = [
      { id: 1, name: item.date },
      { id: 2, name: item.location },
      { id: 3, name: item.organizer },
    ];
    console.log("AND PRINTING singleAccordion", singleAccordion)
    this.state.AccordianPlus.push(singleAccordion)

  });
})
 console.log('AccordionData:', this.state.AccordionData)
 console.log("Did AccordionPlus work?", this.state.AccordianPlus)
 this.state.AccordionData.push(this.state.AccordianPlus)
 console.log("Did final concat work?", this.state.AccordionData)
 } catch (err) {
  console.log('error fetching data: ', err)
 }
 }

 update_Layout = (index) => {

LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);

const array = [...this.state.AccordionData];

array[index]['expanded'] = !array[index]['expanded'];

this.setState(() => {
return {
  AccordionData: array
}
});
}

render() {

if (this.state.isloading){
   return <View><Text>Loading...</Text></View>;
 }
return (
  <View style={styles.MainContainer}>
  <Button
    title="About"
    onPress={() => this.props.navigation.navigate('About')}
  />
  <Text style={styles.Title_Text} > Hello Chess Finder </Text>
  <ScrollView contentContainerStyle={{ paddingHorizontal: 10, 
   paddingVertical: 5 }}>
    {
      this.state.AccordionData.map((item, key) =>
        (
          <Expandable_ListView key={item.category_Name} 
        onClickFunction={this.update_Layout.bind(this, key)} item= . 
     {item} />
        ))
    }
  </ScrollView>

  </View>
  );
 }
 }
Sign up to request clarification or add additional context in comments.

4 Comments

Yes, that worked beautifully. Thank you! I am new to react native and I am always finding that my logic is correct. However I am getting lost in the syntax. I am appending the massaged data into the AccordianData and after massaging, I want to render it. But unfortunately, the render happens before AccordianData is fully set...even using a isrendered flag doesnt seem to work...I am editing my question to add the rest of the code in the class and the render() method. It will be great if you can tell me what's happening here.
I haven't used react-native yet, just react, but I'll do my best
@VijiVedagiri I can't fully understand your code, I suggest using a linter plugin to keep track on posible errors in your files, I'm using eslint with vscode, that help me a lot!
Thanks! I will try that. I think there's a timing issue between render and when the AccordianData array is populated with the data from the database. I have a program that does a nice display of items in the array. I am fetching data from a database using graphql and then populating the data into the array. The render method displays the contents of the array in a collapsed state of the accordion first. It then expands, contracts the items based on user action. But the array is empty when the render method runs and it does not refresh even when i used the isloaded boolean variable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.