dw4050
dw4050

Reputation: 125

Passing data back to prop from Axios with ReactJS Rails 6

I am fairly new at ReactJS. What I'm trying to do is return the user profile with axios and populate the prop with the attributes. I am using fast-jsonapi for retrieving objects from my rails server. It works without issue. Linking ReactJS is confusing me. How can I set the attributes that I retrieve from axios?

user_profile_card.jsx

import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
import axios from 'axios';

const UserProfileCard = props => (
    <div className="box">
        <article className="media">
            <div className="media-left">
                <figure className="image is-64x64">
                    <img src={props.avatar}/>
                </figure>
            </div>
            <div className="media-content">
                <div className="content">
                    <p>
                        <strong>{props.username}</strong> <small>{props.email}</small>
                    </p>
                    <p>
                        Lorem something, something
                    </p>
                </div>
            </div>
        </article>
    </div>
)

UserProfileCard.defaultProps = {
    avatar: "https://bulma.io/images/placeholders/128x128.png",
    username: "borg",
    email: "[email protected]"
}

UserProfileCard.propTypes = {
    avatar: PropTypes.string,
    username: PropTypes.string,
    email: PropTypes.string
}

document.addEventListener('DOMContentLoaded', () => {
    ReactDOM.render(
        <UserProfileCard  />,
        document.getElementById('user_profile')
    )
});

axios.get('api/v1/profile.json').then((response) => {
    if(response.data) {
        console.log(response.data['included'][0]['attributes']['email']) // Works
    }
}).catch(error => console.log(error))

Unable to access data for nested elements below JSON Response

   {data: {…}, included: Array(1)}data: attributes: email: "[email protected]"username: "borg"__proto__: Objectid: "1"relationships: user_profile: data: id: "1"type: "user_profile"__proto__: Object__proto__: Object__proto__: Objecttype: "user"__proto__: Objectincluded: Array(1)0: attributes: {avatar: null, app_theme: "Dark"}id: "1"relationships: {user: {…}}type: "user_profile"__proto__: Objectlength: 1__proto__: Array(0)__proto__: constructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable: ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ valueOf()__defineGetter__: ƒ __defineGetter__()__defineSetter__: ƒ __defineSetter__()__lookupGetter__: ƒ __lookupGetter__()__lookupSetter__: ƒ __lookupSetter__()get __proto__: ƒ __proto__()set __proto__: ƒ __proto__()

Upvotes: 1

Views: 814

Answers (1)

pedrosfdcarneiro
pedrosfdcarneiro

Reputation: 341

You should pass the fetch user logic to inside of the UserProfileCard component, transforming the component into a class component. After that, you can wait until it is mounted and proceed to fetch the profile data. When it's done, you can update the state of your component with the data that was fecthed from the server:

class UserProfileCard extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      avatar: props.avatar,
      username: props.username,
      email: props.email
    }
  }

  componentDidMount() {
    axios.get('api/v1/profile.json').then((response) => {
      if(response.data) {
        this.setState(response.data.data.attributes)
      }
    }).catch(error => console.log(error))
  }

  render() {
    return (
      <div className="box">
          <article className="media">
              <div className="media-left">
                  <figure className="image is-64x64">
                      <img src={this.state.avatar}/>
                  </figure>
              </div>
              <div className="media-content">
                  <div className="content">
                      <p>
                          <strong>{this.state.username}</strong> <small>{this.state.email}</small>
                      </p>
                      <p>
                          Lorem something, something
                      </p>
                  </div>
              </div>
          </article>
      </div>
    )
  }
}

Upvotes: 1

Related Questions