0

I'm making a currency converter app and one of the pages I'm creating for it is meant to use a value chosen from a drop down. I then I want to use that value to make an API call. I have tried several ways to insert the value into the URL and none of them work.

Worldlist.js

import React from 'react';
import { json, checkStatus } from './utils';
import { Link } from 'react-router-dom';

class Worldlist extends React.Component {
  constructor(props) {
    super(props);
    this.state = (props.location && props.location.state) || 
    {
      currencies: {},
      selectStartValue: 'USD',
      selectEndValue: 'EUR',
      startAmount: 1,
      endAmount: 1,
      rates: {},
    };

    this.handleChange = this.handleChange.bind(this);
  }

  //setting the dropdown value when changed
  handleChange(event) {
    const value = event.target.value;
    this.setState({ 
      ...this.state,
      [event.target.name]: value
    });
  }

  //fetching 
  componentDidMount () {
    let { selectStartValue } = this.state;

    let listApi = 'https://api/latest?from=${selectStartValue}'
    let currencyApi = 'https://api/currencies';

    let promise1 = fetch(currencyApi)
    .then(checkStatus)
    .then(json)
    .then((data) => {
      this.setState({ currencies: data });
    })
    .catch((error) => {
      this.setState({ error: error.message });
      console.log(error);
    });

    let promise2 = fetch(listApi)
    .then(checkStatus)
    .then(json)
    .then((data) => {
      this.setState({ rates: data.rates });
    })
    .catch((error) => {
      this.setState({ error: error.message });
      console.log(error);
    });

    Promise.all([promise1, promise2]);
  }

  render() {
    const { currencies, selectStartValue, startAmount, rates } = this.state;

    console.log(rates);
    return (
      <div className="container text-center px-4">
        <div className="row align-items-center row-cols-2 gx-5 ">
          <div className="col-md">
            <div className='form-floating'>
              <select className='form-select' id='floatingSelectGrid' name='selectStartValue' value={selectStartValue} onChange={this.handleChange}>
                <option disabled>Choose your Starting Country</option>
                {Object.keys(currencies).map((sym) => {
                  return <option key={sym} value={sym}>{currencies[sym]}</option>
                })}
              </select>
              <label for='floatingSelectGrid'>Starting Country</label>
            </div>
          </div>
          <div className="col-md">
            <div className='form-floating'>
              <input type='number' className='form-control' name='startAmount' value={startAmount} onChange={this.handleChange} />
            </div>
          </div>
        </div>
        <div className="row align-items-center gx-5 mt-5">
          <div className="col-md">
            <table className="table table-borderless">
              <thead>
                <tr>
                  <th scope='col'>Countries</th>
                  <th scope='col'>Base Rates</th>
                  <th scope='col'>Adjusted Rates</th>
                </tr>
              </thead>
              <tbody>
                {Object.keys(rates).map((sym) => { 
                  return <tr key={sym}>
                    <td>{sym}</td>
                    <td>{rates[sym]}</td>
                  </tr>
                })}
              </tbody>
            </table>
          </div>         
        </div>
      </div>
    )
  }
}

export default Worldlist;

The section that I can't get to work is in the componentDidMount ().

componentDidMount () {
    let { selectStartValue } = this.state;

    let listApi = 'https://api.frankfurter.app/latest?from=${selectStartValue}'

If I use from=USD or from=EUR or from=AUD etc it works great and generates the list.

Even when I console.log(typeof selectStartValue) it returns string so it should work but it doesn't. I tried directly using from=${this.state.selectStartValue} and from=this.state.selectStartValue also.

let { selectStartValue } = this.state;
let term = selectStartValue;

let listApi = 'https://api.frankfurter.app/latest?from=${term}

Also another one of my many failures.

How do I add my selectStartValue into the api url?

AtomicCow
  • 3
  • 2
  • `componentDidMount` only runs once when your component is first mounted. Perhaps you want `componentDidUpdate`? See https://legacy.reactjs.org/docs/react-component.html#updating – Phil Jun 16 '23 at 03:04
  • No this isn't the final program. I run it on mount because if there is a state from one of my other pages I want the list to be rendered immediately. I'm just stuck on this point. I plan to add `componentDidUpdate` later after I solve this issue since I'll be using the same fetch code. – AtomicCow Jun 16 '23 at 03:08
  • 1
    Oh, in that case you're just using the wrong quote characters. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals – Phil Jun 16 '23 at 03:09
  • Dupe ~ [How can I do string interpolation in JavaScript?](https://stackoverflow.com/q/1408289/283366) – Phil Jun 16 '23 at 03:18
  • Thank you so much. That worked and its returning, but now my this.state.rates isnt being set correctly. Oh well back to the drawing board. – AtomicCow Jun 16 '23 at 03:46

0 Answers0