Wątek przeniesiony 2018-08-09 10:45 z C# i .NET przez Patryk27.

Wysłanie ID z komponentu React do kontrolera ASP.NET

0

Hej, piszę do Was, bo się kiszę już od wczoraj nad problemem wysłania productID do metody usuwania w kontrolerze. Wydaje mi się, że mam coś namieszane w handleDeleteProduct, ale mogę się mylić.

Buduję sobie małą aplikację CRUD, na której testuję różne rozwiązania z React, gdzie mój komponent ProductBox wygląda następująco:

import React, { Component } from 'react';
import $ from 'jquery';
import uuid from 'uuid';
import ProductList from '../components/ProductList';
import ProductForm from '../components/ProductForm';

class ProductBox extends React.Component {
    constructor(props) {
        super(props);
        this.state = { data: this.props.initialData };
        this.handleProductSubmit = this.handleProductSubmit.bind(this);
        this.handleDeleteProduct = this.handleDeleteProduct.bind(this);
    }
    loadProductsFromServer() {
        const xhr = new XMLHttpRequest();
        xhr.open('get', this.props.url, true);
        xhr.onload = () => {
            const data = JSON.parse(xhr.responseText);
            this.setState({ data: data });
        };
        xhr.send();
    }
    handleProductSubmit(product) {
        const products = this.state.data;
        product.productID = products.length + 1;
        const newProducts = products.concat([product]);
        this.setState({ data: newProducts });

        const data = new FormData();
        data.append('Name', product.Name);
        data.append('Description', product.Description);

        const xhr = new XMLHttpRequest();
        xhr.open('post', this.props.submitUrl, true);
        xhr.onload = () => this.loadProductsFromServer();
        xhr.send(data);
    }
    handleDeleteProduct(productID) {
        console.log(productID);
        const data = productID;
        const xhr = new XMLHttpRequest();
        xhr.open('post', this.props.deleteUrl, true);
        xhr.onload = () => this.loadProductsFromServer();
        xhr.send(data);
    }
    componentDidMount() {
        window.setInterval(() => this.loadProductsFromServer(), this.props.pollInterval);
    }
    render() {
        return (
            <div className="productBox">
                <h1>Tutaj React z EF</h1>
                <ProductForm onProductSubmit={this.handleProductSubmit} />
                <ProductList onDelete={this.handleDeleteProduct.bind(this)} data={this.state.data} />
            </div>
        );
    }
}

export default ProductBox;

W powyższym komponencie do handleDeleteProduct jest przekazywany productID, i to działa, ponieważ console.log(productID); daje mi integer. Następnie przez XMLHttpRequest próbuję przekazać do poniższej metody kontrolera productID, niestety przy debugowaniu daje mi ona zero:


[Route("comments/delete")]
        [HttpPost]
        public ActionResult DeleteComment(int productID)
        {
            var products = _context.Products;
            foreach(var item in products)
            {
                if(item.ProductID == productID)
                {
                    products.Remove(item);
                    _context.SaveChanges();
                }
            }
            
            return Content("Success :)");
        }

a poniżej fragment app.js dla deleteUrl:

<ProductBox url="/comments" submitUrl="/comments/new" deleteUrl="/comments/delete" pollInterval={2000}/>
0

Przecież w tym handleDeleteProduct nic ze zmienną data nie robisz - nie przekazujesz jej w żaden sposób do żądania.

Btw, poczytaj o Fetch API, a nie bawisz się w XHRy.

0
Patryk27 napisał(a):

Przecież w tym handleDeleteProduct nic ze zmienną data nie robisz - nie przekazujesz jej w żaden sposób do żądania.

Btw, poczytaj o Fetch API, a nie bawisz się w XHRy.

Poprawiłem, zmieniłem wcześniej data na productID w ramach testów. XMLHttpRequest znam z tutka. O Fetch API wcześniej nie słyszałem.

0
Patryk27 napisał(a):

Przecież w tym handleDeleteProduct nic ze zmienną data nie robisz - nie przekazujesz jej w żaden sposób do żądania.

Btw, poczytaj o Fetch API, a nie bawisz się w XHRy.

Ok, przełom. Po kilku godzinach płaszczenia pośladków nad tym problemem udało mi się znaleźć alternatywne rozwiązanie. W zasadzie to załatwia mi sprawę. Zamiast XHR wykorzystałem Ajax z jQuery (znalazłem o nim info w jakimś tutku na css-tricks):

handleDeleteProject(projectID) {
        $.ajax({
            url: './comments/delete',
            data: { productID: projectID },
            type: 'get',
            cache: true,
            success: function (response) {
                console.log("ok");
            },
        });
    }

Bądź co bądź zainteresuję się bliżej tematem Fetch, choć Ajax wydaje mi się bardziej czytelny i transparentny, jako laikowi JS

1

Czyli mówisz, że podłączyłeś całe ogromne jQuery, aby wykorzystać tylko $.ajax?

To może chociaż się na Axiosa przerzuć :-P

0
Patryk27 napisał(a):

Czyli mówisz, że podłączyłeś całe ogromne jQuery, aby wykorzystać tylko $.ajax?

To może chociaż się na Axiosa przerzuć :-P

Słuszna uwaga. Ale chyba mam problem z zamianą data z przykładu $ajax na body w fetch. Aktualnie mam coś takiego:

handleDeleteProject(projectID) {

        fetch('./comments/delete', {
            method: 'get',
            body: { productID: projectID }
        })
            .then(res => res.json())
            .then(res => {
                console.log('usunąłęm produkt:');
                console.log(res);
            })
    }

Niestety nie robi to zupełnie nic, włącznie z błędami i logami:)

1

Zgadujesz, zamiast sporzeć do dokumentacji :-P - body przyjmuje ciąg znaków, nie obiekt:

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
https://stackoverflow.com/questions/29775797/fetch-post-json-data

0
Patryk27 napisał(a):

Zgadujesz, zamiast sporzeć do dokumentacji :-P - body przyjmuje ciąg znaków, nie obiekt:

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
https://stackoverflow.com/questions/29775797/fetch-post-json-data

Gdzieś wcześniej widziałem tę składnię, ale uparłem się na body i to olałem wtedy :D

fetch("/comments/delete?productID=" + encodeURIComponent(projectID))
  .then(res => res.json())
  .then(res => {
    console.log(res);
  })
  .catch(error => {
    console.error(error);
  });
0
Patryk27 napisał(a):

Zgadujesz, zamiast sporzeć do dokumentacji :-P - body przyjmuje ciąg znaków, nie obiekt:

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
https://stackoverflow.com/questions/29775797/fetch-post-json-data

Hej, odgrzewam stary kotlet, bo się zastanawiam, czy da się użyć Fetch z AntiForgeryToken tak jak z Ajax poniżej?
https://stackoverflow.com/questions/14473597/include-antiforgerytoken-in-ajax-post-asp-net-mvc

1 użytkowników online, w tym zalogowanych: 0, gości: 1