3

I am exploring writing single page applications with React on the front end and .NET on the backend (and I am new to both, so apologies if the questions seem simple!). I am using Visual Studio for Mac.

In order to start simple, all my backend code does is returns "Hello, (name of person)" e.g. "Hello, Bob". However, I want the name of the person to be whatever a user inputs into the React form on the web page.

.NET Controller:

namespace TestingReactDotNet.Controllers
{
    [Route("api/[controller]")]
    public class DisplayNameController : Controller
    {
        [HttpGet, Route("Greeting")]
        public string Greeting(string name)
        {
            var greeting = "Hello" + name;
            return greeting;
        }
    }
}


React file (DisplayName.js):



import React, { Component } from "react";

export class DisplayName extends Component {
    state = {
        name: "",
        greeting: ""
    };

    updateInput(key, value) {
    this.setState({
      [key]: value
    });
    }

    calculate(){
        fetch("api/DisplayName/Greeting")
            .then(response => response.text())
            .then(data => {
                this.setState({ greeting: data });
            });
           <h1>this.state.greeting</h1>
  }



  render() {
    return (
      <center>
        <div className="App">
          <div>
            Type a word...
            <br />
            <input
              type="text"
              placeholder="Type word here ..."
              value={this.state.name}
               onChange={e => this.updateInput("name", e.target.value)}
               />
               <button onClick={() => this.calculate()}>Submit</button>
              <br />
          </div>
        </div>
      </center>
    );
  }
}

My question is:

  1. How do I get the frontend and backend to talk to each other here, so that whatever name the user inputs into the form, the DisplayName method can use in order to return the string which is then displayed on the page?

I appreciate it's probably easier just to do this using React alone, but I am really trying to ensure that I can use React and .NET together, so any advice is really appreciated.

Thanks :)

juemura7
  • 411
  • 9
  • 20
  • 2
    It sounds like what you are missing is how to send a request body with the Javascript `fetch` API, and how to accept a request body in your .NET API. For `fetch` with a body, see this example https://googlechrome.github.io/samples/fetch-api/fetch-post.html. For the .NET side, you would want to create a class that has the same structure as the body of your request, and make that a parameter to your endpoint, instead of just a string. – JamesFaix Aug 29 '19 at 20:03

1 Answers1

3

Your code is excellent. But there is only one problem: when you got the result from the server, you do it nothing!

Look at your calculate() method:

calculate(){
        fetch("api/DisplayName/Greeting")
            .then(response => response.text())
            .then(data => {
                this.setState({ greeting: data });
            });
           <h1>this.state.greeting</h1>
  }

What does the last line do? It creates a meaningless element that won't appear in any place! (also, you forgot the curly braces around this.state.greeting).

Instead, you should use the following approach: render the form if the it's not submitted yet, otherwise render the answer (it's just an example; you can render the both (if available) and more):

calculate(){
        fetch("api/DisplayName/Greeting")
            .then(response => response.text())
            .then(data => {
                this.setState({ greeting: data });
            });
  }

render() {
  if ('' !== this.state.greeting) {
    // We already submitted the form, show welcome message
    return <h1>{this.state.greeting}</h1>
  } else {
    // As your code
    // ...
  }
}

Edit:

After your comment, I noticed why your server doesn't receive the name: it's simple - you don't send it!

So, How To Send Parameters To ASP.NET Backend With The Fetch API?

I'll discuss it shortly; it is very wide subject. I you want a comprehesive explanation, google for "ASP.NET Core Model Binding" and "js fetch api".

Let's start with the client side:

There are some ways to send data using fetch(): the simplest are query string (http://...?w=x&y=z) and using the body option, which accepts string that may be json, for example.

But the body parameter not works for get request. So, we'll use query string. Your case is simple enough to simply concatenate the strings, for more complex cases, see Setting query string using Fetch GET request.

Update your client code as follows:

// ...
fetch('/api/DisplayName/Greeting?name=' + encodeURIComponent(this.state.name))
// ...

(We're using encodeURIComponent() which encodes a string to be inside the query string).

In the server side, this is automatically, very luickly!

But to learn: what's happen?

In ASP.NET, there is a concept called Model Binding: The ability to take parameters from the request and make them parameter of the controller method.

There are some builtin model binders in ASP.NET (you can build your own, but in most cases you don't), our important is:

1) Query string model binder, which takes the query string parameters and pass them as arguments with the same name to the controller.

2) JSON model binder, which if the content-type is json, parses it and pass it too.

There are much more model binders.

These binders can handle also arrays (including the query string (in special form)!), nested object properties (which can lead to overposting attack) and more.

So, the only thing you need is to pass the parameter, then the model binder will do all the work automatically for you!

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
  • Thanks so much for this @ChayimFriedman ! I have amended my code with your suggestions. However, it seems that my backend `DisplayName` function is still not reading the user input. Do you know how I can pass the name the user inputs as the argument to the `DisplayName` function? At the moment all that renders on screen is "Hello" – juemura7 Aug 29 '19 at 20:32
  • I cannot thank you enough for that edit and explanation ! :D – juemura7 Aug 30 '19 at 07:51