简体   繁体   中英

Parse JSON object in Flatlist React Native

I am new in React Native, I am developing an application like Ecommerce App, I am using Woocommerce (Wordpress) as backend and through Woocomrce Api response I am trying to implement in my React Native App, but I have one problem while parsing JSON. Basically I don't konw how to parse images array in flatlist. My code and API response are mentioned below, I remind you that item.images[0].src is not working. Thank you in advance.

My Woocommerce API Response

{
  "id": 794,
  "name": "Premium Quality",
  "slug": "premium-quality-19",
  "permalink": "https://example.com/product/premium-quality-19/",
  "date_created": "2017-03-23T17:01:14",
  "date_created_gmt": "2017-03-23T20:01:14",
  "date_modified": "2017-03-23T17:01:14",
  "date_modified_gmt": "2017-03-23T20:01:14",
  "type": "simple",
  "status": "publish",
  "featured": false,
  "catalog_visibility": "visible",
  "description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>\n",
  "short_description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>\n",
  "sku": "",
  "price": "21.99",
  "regular_price": "21.99",
  "sale_price": "",
  "date_on_sale_from": null,
  "date_on_sale_from_gmt": null,
  "date_on_sale_to": null,
  "date_on_sale_to_gmt": null,
  "price_html": "<span class=\"woocommerce-Price-amount amount\"><span class=\"woocommerce-Price-currencySymbol\">&#36;</span>21.99</span>",
  "on_sale": false,
  "purchasable": true,
  "total_sales": 0,
  "virtual": false,
  "downloadable": false,
  "downloads": [],
  "download_limit": -1,
  "download_expiry": -1,
  "external_url": "",
  "button_text": "",
  "tax_status": "taxable",
  "tax_class": "",
  "manage_stock": false,
  "stock_quantity": null,
  "stock_status": "instock",
  "backorders": "no",
  "backorders_allowed": false,
  "backordered": false,
  "sold_individually": false,
  "weight": "",
  "dimensions": {
    "length": "",
    "width": "",
    "height": ""
  },
  "shipping_required": true,
  "shipping_taxable": true,
  "shipping_class": "",
  "shipping_class_id": 0,
  "reviews_allowed": true,
  "average_rating": "0.00",
  "rating_count": 0,
  "related_ids": [
    53,
    40,
    56,
    479,
    99
  ],
  "upsell_ids": [],
  "cross_sell_ids": [],
  "parent_id": 0,
  "purchase_note": "",
  "categories": [
    {
      "id": 9,
      "name": "Clothing",
      "slug": "clothing"
    },
    {
      "id": 14,
      "name": "T-shirts",
      "slug": "t-shirts"
    }
  ],
  "tags": [],
  "images": [
    {
      "id": 792,
      "date_created": "2017-03-23T14:01:13",
      "date_created_gmt": "2017-03-23T20:01:13",
      "date_modified": "2017-03-23T14:01:13",
      "date_modified_gmt": "2017-03-23T20:01:13",
      "src": "https://example.com/wp-content/uploads/2017/03/T_2_front-4.jpg",
      "name": "",
      "alt": ""
    },
    {
      "id": 793,
      "date_created": "2017-03-23T14:01:14",
      "date_created_gmt": "2017-03-23T20:01:14",
      "date_modified": "2017-03-23T14:01:14",
      "date_modified_gmt": "2017-03-23T20:01:14",
      "src": "https://example.com/wp-content/uploads/2017/03/T_2_back-2.jpg",
      "name": "",
      "alt": ""
    }
  ],
  "attributes": [],
  "default_attributes": [],
  "variations": [],
  "grouped_products": [],
  "menu_order": 0,
  "meta_data": [],
  "_links": {
    "self": [
      {
        "href": "https://example.com/wp-json/wc/v3/products/794"
      }
    ],
    "collection": [
      {
        "href": "https://example.com/wp-json/wc/v3/products"
      }
    ]
  }
}

My APP.js Code

 import React, { Component } from 'react';
    import { View, Text, Image, Dimensions, ActivityIndicator, StatusBar, FlatList } from 'react-native';
    import WooCommerceAPI from 'react-native-woocommerce-api';

var WooCommerceApp = new WooCommerceAPI({
    url: 'http://store.oruga.in/', // Your store URL
    ssl: true,
    consumerKey: 'ck_113e04d8a91ce34cbfeaf21971b6d5e18e7XXXXX', // Your consumer secret
    consumerSecret: 'cs_fd0f4b6a5573837b1f7732a98dccb355a233XXXXX', // Your consumer secret
    wpAPI: true, // Enable the WP REST API integration
    version: 'wc/v3', // WooCommerce WP REST API version
    queryStringAuth: true
});

export default class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            responsedata: [],
            loading: true
        };
        WooCommerceApp.get('products/')
            .then(data => {
                this.setState({ responsedata: data }, () => {
                    this.setState({ loading: false });
                });
            })
            .catch(error => {
                console.log(error);
            });

    }

    render() {
        return (
            <View>
                <StatusBar hidden />
                {this.state.loading === true ? (
                    <View style={{ justifyContent: 'center', alignItems: 'center', height: Dimensions.get('window').height }}>
                        <ActivityIndicator size="large" color="#0f3443" />
                    </View>
                ) : (
                        <View>
                            <FlatList
                                data={this.state.responsedata}
                                keyExtractor={this._keyExtractor}
                                renderItem={({ item }) => (
                                    <View>
                                        <Image source={{ uri: item.images[0].src }} />
                                        <Text >{item.name}</Text>
                                    </View>

                                )} />
                        </View>)
                }
            </View>
        );
    }
}

You should pass an array as data to your FlatList , in your example you passed a JSON object to your flatlist that's why it doesn't render any thing. Also you should pass height and width to you image or it will not show.

Change your flatlist like this and it should work.

<View>
  <FlatList
    data={this.state.responsedata.images}
    keyExtractor={item => `${item.id}`}
    renderItem={({ item }) => (
      <View>
        <Image style={{ height: 100, width: 100 }} source={{ uri: item.src }} />
        <Text>{item.name}</Text>
      </View>

    )}
  />
</View>

Other thing, don't call setState in your constructor, it will show you a warning. Move the api call to componentDidMount function:

componentDidMount() {
  WooCommerceApp.get('products/')
    .then((data) => {
      this.setState({ responsedata: data }, () => {
        this.setState({ loading: false });
      });
    })
    .catch((error) => {
      console.log(error);
    });
}

Edit: If you need the response json then you don't need FlatList, FlatList is to show a List of items. And if you want to show only first image then change your FlatList like this

<Image style={{ height: 100, width: 100 }} source={{ uri: this.state.responsedata.images[0].src }} />

i know this is an old question but the answer might be helpful for others like me. i had also came across this situation when using WC api. the solution is to use

const image = item.images.slice(0,1).pop(); to get the first object from the inner image array and display it using

 <Image
        source={{ uri: image.src }}
        resizeMode={'contain'}
        style={{flex:1, width: '100%', height: 150 }}
    />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM