7

Not allowed to say help in title but I need help understanding this template. I am trying to use the ASP.NET Core Web Application React project template for the first time. I am already somewhat familiar with React but not this project template. The template comes with a small weather api to which the FetchData page makes a fetch request.

First of all, I can not figure out where exactly React is making the request from and second I can not figure out how to replicate this.

This is the Fetch Data method:

FetchData

import React, { Component } from 'react';

export class FetchData extends Component {
  static displayName = FetchData.name;

  constructor(props) {
    super(props);
    this.state = { forecasts: [], loading: true };
  }

  componentDidMount() {
    this.populateWeatherData();
  }

  static renderForecastsTable(forecasts) {
    return (
      <table className='table table-striped' aria-labelledby="tabelLabel">
        <thead>
          <tr>
            <th>Date</th>
            <th>Temp. (C)</th>
            <th>Temp. (F)</th>
            <th>Summary</th>
          </tr>
        </thead>
        <tbody>
          {forecasts.map(forecast =>
            <tr key={forecast.date}>
              <td>{forecast.date}</td>
              <td>{forecast.temperatureC}</td>
              <td>{forecast.temperatureF}</td>
              <td>{forecast.summary}</td>
            </tr>
          )}
        </tbody>
      </table>
    );
  }

  render() {
    let contents = this.state.loading
      ? <p><em>Loading...</em></p>
      : FetchData.renderForecastsTable(this.state.forecasts);

    return (
      <div>
        <h1 id="tabelLabel" >Weather forecast</h1>
        <p>This component demonstrates fetching data from the server.</p>
        {contents}
      </div>
    );
  }

  async populateWeatherData() {
    const response = await fetch('weatherforecast');
    const data = await response.json();
    this.setState({ forecasts: data, loading: false });
  }
}

This all makes perfect sense to me except this line: const response = await fetch('weatherforecast');. I'm having a hard time understanding where exactly 'weatherforecast' is.

Now here is the WeatherForecast controller:

WeatherForecastController

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ReactFront.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

And this is I'm assuming something like a model class for WeatherForecast

WeatherForecast.cs

using System;

namespace ReactFront
{
    public class WeatherForecast
    {
        public DateTime Date { get; set; }

        public int TemperatureC { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

        public string Summary { get; set; }
    }
}

And this is the result of fetching weatherforecast:

weatherforecast

However, I can not replicate this using my own controller. For example, I have created this simple controller:

ValuesController

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ReactFront.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ValuesController : ControllerBase
    {
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "Value1", "Value2", "Value3" };
        }

        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "The vlaue is " + id;
        }
    }
}

And replicated the view like this:

FetchValues

import React, { Component } from 'react';

export class FetchValues extends Component {
    static displayName = FetchValues.name;

    constructor(props) {
        super(props);
        this.state = { apiValues: [], loading: true };
    }

    componentDidMount() {
        this.populateValuesData();
    }

    static renderValuesTable(apiValues) {
        return (
            <table className='table table-striped' aria-labelledby="tabelLabel">
                <thead>
                    <tr>
                        <th>Value</th>
                    </tr>
                </thead>
                <tbody>
                    {apiValues.map(apiValues =>
                        <tr key={apiValues.value}>
                            <td>{apiValues.value}</td>
                        </tr>
                    )}
                </tbody>
            </table>
        );
    }

    render() {
        let contents = this.state.loading
            ? <p><em>Loading...</em></p>
            : FetchValues.renderValuesTable(this.state.apiValues);

        return (
            <div>
                <h1 id="tabelLabel" >Values from API</h1>
                <p>This component demonstrates fetching data from the server.</p>
                {contents}
            </div>
        );
    }

    async populateValuesData() {
        const response = await fetch('values');
        const data = await response.json();
        this.setState({ apiValues: data, loading: false });
    }
}

When I access the FetchValues page I get this error:

Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0        fetch-values:1

And checking Inspect -> Network -> Preview -> values (or fetch-values) the preview is empty.

Here are my questions:

1.) Where exactly is weatherforecast and how do I see it so that I can replicate what is happening with my values?

2.) Why is values empty in the preview? The same code works perfectly in the API project template.

3.) Does there exist any official docs on this project template? I can't find more than 1 unhelpful page: https://learn.microsoft.com/en-us/aspnet/core/client-side/spa/react?view=aspnetcore-5.0&tabs=visual-studio

4
  • Ahh thank you so much @mxmissile I can't believe I made such a simple mistake. 1 more thing, in the table that is supposed to show the values it only prints "Value" one time. How can I get it to show "Value1", "Value2", "Value3"? Commented Jul 19, 2021 at 12:17
  • "Each child in a list should have a unique ID prop" Commented Jul 19, 2021 at 12:34
  • I added the typo fix as an answer below. As for your second question, since its unrelated you are going to want to create a new separate question. That will make it easier to answer and will help others. Remove the unrelated text and code. Commented Jul 19, 2021 at 14:37
  • 1
    @mxmissile I figured it out it was another dumb mistake. Thank you! Commented Jul 19, 2021 at 17:10

2 Answers 2

4

You have a typo in your fetch call:

Change fetch('values'); to fetch('api/values');.

Sign up to request clarification or add additional context in comments.

Comments

-1

on WeatherForecastController.cs file, look at line 11 [Route("[controller]")] that's the clue. 'weatherforecast' replaces the value of [controller] and the file has WeatherForecast init so the system automatically makes the connection.

for your case, you're routing to [Route("api/[controller]")] so you need to put 'api/' for your fetch request followed by class name.

Comments

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.