0

I'm experiencing an issue displaying the card data coming from the API source. Can anyone help on this? What am I missing?

questionTwo.js

import React, { Component} from 'react'
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Typography from '@material-ui/core/Typography';
import { withStyles } from '@material-ui/core/styles';

import CircularProgress from '@material-ui/core/CircularProgress';

import { getCardDetails } from './api'
import styles from './styles'

class QuestionTwo extends Component {
    constructor(props){
        super(props);
        this.state = {
            title: null,
            imgSrc: null,
            body: '',
            loading: true,
        };
        getCardDetails.then(({title, imgSrc, body}) =>{
            this.setState({
                title:  title,
                imgSrc: imgSrc,
                body: body,
                loading: false,
            })
        })
    }
    render(){
        const { classes } = this.props;
        const { title, imgSrc, body, loading }  = this.state;
        if(loading){
            return (
                <div className={classes.spinner}>
                    <CircularProgress/>
                </div>
            )
        }
        return(
            <div className={classes.container}>
                <Card className={classes.card}>
                    <CardMedia
                        className={classes.media}
                        image={imgSrc}
                        title={title}
                    />
                    <CardContent className={classes.content}>
                        <Typography gutterBottom variant="h5" component="h2">
                            {title}
                        </Typography>
                        <div
                            className={classes.body}
                            dangerouslySetInnerHTML={{__html:body}}
                        />
                    </CardContent>
                </Card>
            </div>
        )
    }
}

export default withStyles(styles)(QuestionTwo);

question.js

import React from 'react'
import Typography from "@material-ui/core/Typography";
import Link from '@material-ui/core/Link';
import {CardMedia} from "@material-ui/core";
import Solution from "./images/solution.png";

const question = () =>{
    return (
        <div>
            <Typography variant="h4" gutterBottom>
                Question Two
            </Typography>
            <Typography variant="h5" gutterBottom>
                Api Call
            </Typography>
            <Typography variant="body1" gutterBottom>
                If you started this application with 'yarn start' a json server should now be running on port 3001
            </Typography>
            <Typography variant="body1" gutterBottom>
                The Api can be found here:
                <Link href="http://localhost:3001/example" target="_blank" >
                    http://localhost:3001/example
                </Link>
            </Typography>
            <Typography variant="body1" gutterBottom>
                Your task if you choose to accept it, is to resolve this bug (displayed on the right and in the console) so that the card component displays the data from the API.
            </Typography>
            <Typography variant="body1" gutterBottom>
                As with all the questions in this tech test, you may or may not wish to refactor some of the code.
            </Typography>
            <Typography variant="h6" gutterBottom>
                Below is what the final solution should look like.
            </Typography>
            <CardMedia
                image={Solution}
                style={{
                    width: '100%',
                    height: 500,
                    backgroundSize: 'contain',
                }}
                title="The Solution"
            />
        </div>
    )
};

export default  question

index.js

import React from 'react';
import ErrorBoundary from "../../components/errorBoundary";
import QuestionTwo from './questionTwo'
import Question from './question'

const QuestionTwoWrapper = () =>(
    <ErrorBoundary question={Question}>
        <QuestionTwo />
    </ErrorBoundary>
);

export default QuestionTwoWrapper

api.js

import axios from "axios";

async function getCardDetails (){
    let newPromise = new Promise((resolve, reject)=>{
        axios.get('http://localhost:3001/example').then((result)=>{
            const {title, body, imgSrc} = result.data;
            resolve(title, body, imgSrc)
        });
    });
    return newPromise
}

export { getCardDetails }

I've considered altering the entries in webpack.config.js (as recommended at TypeError: __webpack_require__.i(...) is not a function) however I cannot find one that looks usable (except in ..\master\node_modules\react-scripts\config but cannot see suitable points to add additional line).

1 Answers1

0

After providing api.js, you can see, that getCardDetails is a function that returns a Promise. So you need to call it before you can use .then:

constructor(props){
    super(props);
    this.state = {
        title: null,
        imgSrc: null,
        body: '',
        loading: true,
    };
    getCardDetails().then(({title, imgSrc, body}) =>{
        this.setState({
            title:  title,
            imgSrc: imgSrc,
            body: body,
            loading: false,
        })
    })
}
DarkLegend
  • 1,706
  • 1
  • 11
  • 10
  • Thanks but sorry - got to be honest. I don't get what you're saying here? Also what you've pasted is the same as what is present in questionTwo.js already. – JB Benjamin Apr 26 '20 at 14:34
  • Sorry, not sure how to highlight the bracket within code. There is a minor difference - see the brackets: getCardDetails().then( – DarkLegend Apr 27 '20 at 07:25
  • Thanks. Much appreciated. It's what happens when you look at stuff at 2am. Lolz. Tried it but leads to a blank screen with a tall empty card in the middle? – JB Benjamin Apr 27 '20 at 11:28