FormData es vacío en los padres cuando se pasa de niño componente

0

Pregunta

Principiante Alerta! :) Estoy configurando el objeto FormData infantil en el componente y, a continuación, pasar a los padres de componente mediante formReducer y el envío, pero en los padres formData.entradas() siempre está vacío!

ChildComponent.js

function ChildComponent({signed, fileAttached}){
    const { dispatch } = useContext(ContactFormContext);

     const changeHandler = (event) => {

const formData = new FormData();

formData.append('File', event.target.files[0]);


dispatch({ type: "FILE_ATTACHED", payload: formData })
};

return (
<>
            <div>
        <input type="file" name="file" onChange={changeHandler} />
    </div>
</>);
}

ParentComponent.js

function useFormProgress(fileAttached) {
     
     
    function goForward() {
        const currentStep = 1;

        let appvariables = [
                {
                  "key": "PUID",
                  "value": "a2sd"
                },
                {
                  "key": "ApplicationNames",
                  "value": "Trello, abc"
                }
              ];
        switch(currentStep) {
          case 0:
            break;
          case 1:
            console.log(fileAttached);
          if(fileAttached != null)
              sendEmail("Resignation Letter", appvariables, fileAttached);
          break;
        }
    }
    return [goForward];
}

function sendEmail(templateName, variables, attachment){
  console.log("sending email...");
    const requestBody = {
                    "templateName": templateName,
                    "recipients": [    
                    "[email protected]"
                    ],
                    "variables":  variables,
                    "files": attachment
                };

fetch('https://localhost:5001/api/Email',{
  method:'Post',
  body: JSON.stringify(requestBody),
  headers:{'Content-Type': 'application/json'},
 });

}

const initialState = {
      signed: "",
      fileAttached: null
};

function formReducer(state, action) {
   switch (action.type) {
    case "SIGNED":
      return { ...state, signed: action.payload };
    case "FILE_ATTACHED":
      return {...state, fileAttached: action.payload};
    default:
      throw new Error();
  }
}


function ParentComponent() {

   const [state, dispatch] = useReducer(formReducer, initialState);
     const { signed, fileAttached } = state;

     const steps = [<ChildComponent {...{signed, fileAttached}}/>];

   const [goForward] = useFormProgress(fileAttached);


    return (
        <ContactFormContext.Provider value={{ dispatch }}>
          <div>{steps[0]}
        <div><button onClick={e => {
           e.preventDefault();
              goForward();
        }}
             
        >  Parent Button
        </button>
        </div>
    </div>
        </ContactFormContext.Provider>
       );
}

ContactFormContext.js

const ContactFormContext = React.createContext();

En la instrucción switch de arriba (ParentComponent), el de la consola.log(FileAttached) muestra el objeto FormData con las entradas de 0(ver imagen adjunta), también la solicitud de la API no es correcta.!

enter image description here

puedes probarlo en https://jscomplete.com/playground

  1. para añadir un contexto en la parte superior

  2. agregar niño código de componente

  3. agregar parentcomponent código

  4. agregue la siguiente línea

      ReactDOM.render(<ParentComponent/>, mountNode);
    

MyAPI Método

[HttpPost]
    public JsonResult Get(EmailRequest email)
    {
         //the request never comes here
     }

EmailRequest.cs

public class EmailRequest
{
    public string TemplateName { get; set; }
    public string[] Recipients { get; set; }
    public List<Variables> Variables { get; set; }
    public FormFileCollection files { get; set; }
}
asp.net-web-api c# file-upload form-data
2021-11-23 09:18:20
3

Mejor respuesta

1

Con el fin de obtener los valores de las entradas método de FormData mediante el uso de la consola.registro usted debe hacer esto de esta manera:

  for (var [key, value] of attachment.entries()) {
    console.log("log from for loop", key, value);
  }

también, si desea enviar un archivo al servidor mediante solicitud POST, no se puede stringify archivo que desea enviar. Lo que se está enviando actualmente en su json carga se parece a esto "files": {}. Usted necesita para serializar en una manera diferente. Esto significa que usted necesita para cambiar la forma en que quieres que se envíe este archivo. Revisa las respuestas de esta pregunta: Cómo hago para subir un archivo con el JS de captura de la API?

Para serializar el objeto FormData, usted puede comprobar este post: https://gomakethings.com/serializing-form-data-with-the-vanilla-js-formdata-object/

2021-11-23 10:24:12
0

He añadido sus códigos en codesandbox y todo parece estar bien.

Codesandbox demo

enter image description here

2021-11-23 10:15:22
0

Así que, a partir de Lazar Nikolic la respuesta de arriba para dejar de tratar de json.stringify!.. tras el tropiezo en un par de los bloqueadores de aquí y allí por fin puedo enviar un Archivo con éxito a la API!!

Aquí hay algunos pasos importantes a tener en cuenta:

En el backend - he cambiado de método de controlador:

  1. Añadido [FromForm] de la etiqueta

    [HttpPost]
     public JsonResult Get([FromForm] EmailRequest email)
    

Este post me ayudó.

En el Front-end lado

  1. Cambiado ChildComponent.js de la siguiente manera

    function ChildComponent({signed, fileAttached}){
    const { dispatch } = useContext(ContactFormContext);
    
    const changeHandler = (event) => {
    
    dispatch({ type: "FILE_ATTACHED", payload: event.target.files[0] })
    };
    
    return (
    <>
         <div>
     <input type="file" name="file" onChange={changeHandler} />
    </div>
    </>);
    }
    
  2. Cambiado sendEmail función en ParentComponent.js de la siguiente manera

    function sendEmail(templateName, variables, attachment){
      console.log("sending email...");
    
      const formData = new FormData();
    
     formData.append('files', attachment);
     formData.append('templateName', templateName);
     formData.append('recipients', [    
      "[email protected]"
     ]);
     formData.append('variables', variables);
    
    
    fetch('https://localhost:5001/api/Email',{
    method:'Post',
    body: formData,
    //headers:{'Content-Type': 'application/json'},
    });
    
    }
    
  3. Aviso el correo electrónico objeto de ser recibidas como resultado tenía todas las propiedades de conjunto como null hasta que se me quita el encabezado de tipo de Contenido y, a continuación, el navegador va a agregar multipart/form-data misma cabecera.. tengo esta ayuda de @madhu131313 comentario aquí

  4. no podemos pasar un array de objetos directamente en el formulario de datos para las variables de la matriz estaba vacía..hice lo siguiente

    for(let i = 0; i < variables.length; i++){
     formData.append(`variables[` + i + `].key`, variables[i].key);
     formData.append(`variables[` + i + `].value`, variables[i].value);
    }
    

en lugar de

   formData.append('variables', variables);

y cambiado los destinatarios de la siguiente manera:

   let recipients = [    
  "[email protected]",
  "[email protected]",
  "[email protected]"
  ];

   for(let i = 0; i < recipients.length; i++){
    formData.append(`recipients[` + i + `]`, recipients[i]);
  }
2021-11-23 10:22:16

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................