у объекта, возвращаемого из веб-api, отсутствуют некоторые свойства reactjs

#javascript #reactjs #api

#javascript #reactjs #API

Вопрос:

Я новичок в reactjs и был бы признателен за небольшую помощь здесь. Мой reactjs spa потребляет из Asp.Net Веб-Api. Когда я делаю запрос get через postman, он возвращает все свойства / информацию из базы данных. Но когда это делается с помощью моего приложения react, оно возвращает всего пару свойств, исключая остальные. Я вставлю ниже коды компонентов fetch wrapper, @service и page.

Извлекать оболочку

 import config from 'config';
import { healthcareProviderService } from '@/_services';

export const fetchWrapperHealthcareProvider = {
    get,
    post,
    put,
    delete: _delete
}

function get(url) {
     const requestOptions = {
         method: 'GET',
         headers: authHeader(url)
     };
     return fetch(url, requestOptions).then(handleResponse);
}

function post(url, body) {
    const requestOptions = {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', ...authHeader(url) },
        credentials: 'include',
        body: JSON.stringify(body)
    };
    return fetch(url, requestOptions).then(handleResponse);
}

function put(url, body) {
    const requestOptions = {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json', ...authHeader(url) },
        body: JSON.stringify(body)
    };
    return fetch(url, requestOptions).then(handleResponse);    
}

// prefixed with underscored because delete is a reserved word in javascript
function _delete(url) {
    const requestOptions = {
        method: 'DELETE',
        headers: authHeader(url)
    };
    return fetch(url, requestOptions).then(handleResponse);
}

// helper functions

function authHeader(url) {
    // return auth header with jwt if user is logged in and request is to the api url
    const user = healthcareProviderService.userValue;
    const isLoggedIn = user amp;amp; user.jwtToken;
    const isApiUrl = url.startsWith(config.apiUrl);
    if (isLoggedIn amp;amp; isApiUrl) {
        return { Authorization: `Bearer ${user.jwtToken}` };
    } else {
        return {};
    }
}

function handleResponse(response) {
    return response.json().then(text => {
        const data = text amp;amp; JSON.parse(text);
        
        if (!response.ok) {
            if ([401, 403].includes(response.status) amp;amp; healthcareProviderService.userValue) {
                // auto logout if 401 Unauthorized or 403 Forbidden response returned from api
                healthcareProviderService.logout();
            }

            const error = (data amp;amp; data.message) || response.statusText;
            return Promise.reject(error);
        }

        return data;
    });
}
 

healthProviderService от @service

 import { BehaviorSubject } from 'rxjs';

import config from 'config';
import { fetchWrapperHealthcareProvider, history } from '@/_helpers';

const userSubject = new BehaviorSubject(null);
const baseUrl = `${config.apiUrl}/healthcareprovider`;

export const healthcareProviderService = {
    login,
    logout,
    refreshToken,
    register,
    verifyEmail,
    forgotPassword,
    validateResetToken,
    resetPassword,
    getAll,
    getById,
    create,
    update,
    delete: _delete,
    user: userSubject.asObservable(),
    get userValue () { return userSubject.value }
};

function login(email, password) {
    return fetchWrapperHealthcareProvider.post(`${baseUrl}/authenticate`, { email, password })
        .then(user => {
            // publish user to subscribers and start timer to refresh token
            userSubject.next(user);
            startRefreshTokenTimer();
            return user;
        });
}

function logout() {
    // revoke token, stop refresh timer, publish null to user subscribers and redirect to login page
    fetchWrapperHealthcareProvider.post(`${baseUrl}/revoke-token`, {});
    stopRefreshTokenTimer();
    userSubject.next(null);
    history.push('/account/login');
}

function refreshToken() {
    return fetchWrapperHealthcareProvider.post(`${baseUrl}/refresh-token`, {})
        .then(user => {
            // publish user to subscribers and start timer to refresh token
            userSubject.next(user);
            startRefreshTokenTimer();
            return user;
        });
}

function register(params) {
    return fetchWrapperHealthcareProvider.post(`${baseUrl}/register`, params);
}

function verifyEmail(token) {
    return fetchWrapperHealthcareProvider.post(`${baseUrl}/verify-email`, { token });
}

function forgotPassword(email) {
    return fetchWrapperHealthcareProvider.post(`${baseUrl}/forgot-password`, { email });
}

function validateResetToken(token) {
    return fetchWrapperHealthcareProvider.post(`${baseUrl}/validate-reset-token`, { token });
}

function resetPassword({ token, password, confirmPassword }) {
    return fetchWrapperHealthcareProvider.post(`${baseUrl}/reset-password`, { token, password, confirmPassword });
}

function getAll() {
    return fetchWrapperHealthcareProvider.get(baseUrl);
}

function getById(id) {
    return fetchWrapperHealthcareProvider.get(`${baseUrl}/${id}`);
}

function create(params) {
    return fetchWrapperHealthcareProvider.post(baseUrl, params);
}

function update(id, params) {
    return fetchWrapperHealthcareProvider.put(`${baseUrl}/${id}`, params)
        .then(user => {
            // update stored user if the logged in user updated their own record
            if (user.id === userSubject.value.id) {
                // publish updated user to subscribers
                user = { ...userSubject.value, ...user };
                userSubject.next(user);
            }
            return user;
        });
}

// prefixed with underscore because 'delete' is a reserved word in javascript
function _delete(id) {
    return fetchWrapperHealthcareProvider.delete(`${baseUrl}/${id}`)
        .then(x => {
            // auto logout if the logged in user deleted their own record
            if (id === userSubject.value.id) {
                logout();
            }
            return x;
        });
}

// helper functions

let refreshTokenTimeout;

function startRefreshTokenTimer() {
    // parse json object from base64 encoded jwt token
    const jwtToken = JSON.parse(atob(userSubject.value.jwtToken.split('.')[1]));

    // set a timeout to refresh the token a minute before it expires
    const expires = new Date(jwtToken.exp * 1000);
    const timeout = expires.getTime() - Date.now() - (60 * 1000);
    refreshTokenTimeout = setTimeout(refreshToken, timeout);
}

function stopRefreshTokenTimer() {
    clearTimeout(refreshTokenTimeout);
}
 

Обновить компонент страницы

 import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import { Formik, Field, Form, ErrorMessage } from 'formik';
import * as Yup from 'yup';

import { healthcareProviderService, alertService } from '@/_services';

function Update({ history }) {
    const user = healthcareProviderService.userValue;
    const initialValues = {
        fullName: user.fullName,
        email: user.email,
        role: user.role,
        street: user.street,
        city: user.city,
        state: user.state,
        zipCode: user.zipCode,
        password: '',
        confirmPassword: ''
    };

    const validationSchema = Yup.object().shape({
        fullName: Yup.string()
            .required('Name is required'),
        email: Yup.string()
            .email('Email is invalid')
            .required('Email is required'),
        role: Yup.string()
            .required('Role is required'),
        street: Yup.string()
            .required('Street is required'),
        city: Yup.string()
            .required('City is required'),
        state: Yup.string()
            .required('State is required'),
        zipCode: Yup.string()
            .required('ZipCode is required'),
        password: Yup.string()
            .min(6, 'Password must be at least 6 characters'),
        confirmPassword: Yup.string()
            .when('password', (password, schema) => {
                if (password) return schema.required('Confirm Password is required');
            })
            .oneOf([Yup.ref('password')], 'Passwords must match')
    });

    function onSubmit(fields, { setStatus, setSubmitting }) {
        setStatus();
        healthcareProviderService.update(user.id, fields)
            .then(() => {
                alertService.success('Update successful', { keepAfterRouteChange: true });
                history.push('.');
            })
            .catch(error => {
                setSubmitting(false);
                alertService.error(error);
            });
    }

    const [isDeleting, setIsDeleting] = useState(false);
    function onDelete() {
        if (confirm('Are you sure?')) {
            setIsDeleting(true);
            healthcareProviderService.delete(user.id)
                .then(() => alertService.success('Account deleted successfully'));
        }
    }

    return (
        <Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={onSubmit}>
            {({ errors, touched, isSubmitting }) => (
                <Form>
                    <h1>Update Profile</h1>
                    <div className="form-row">
                            <div className="form-group col-4">
                                <label>Full Name</label>
                                <Field name="fullName" type="text" className={'form-control'   (errors.fullName amp;amp; touched.fullName ? ' is-invalid' : '')} />
                                <ErrorMessage name="fullName" component="div" className="invalid-feedback" />
                            </div>
                            <div className="form-group col-4">
                                <label>Email</label>
                                <Field name="email" type="text" className={'form-control'   (errors.email amp;amp; touched.email ? ' is-invalid' : '')} />
                                <ErrorMessage name="email" component="div" className="invalid-feedback" />
                            </div>
                            <div className="form-group col-4">
                                <label>Role</label>
                                <Field name="role" as="select" className={'form-control'   (errors.role amp;amp; touched.role ? ' is-invalid' : '')}>
                                    <option value=""></option>
                                    <option value="HealthcareProvider">healthcareProvider</option>
                                </Field>
                                <ErrorMessage name="role" component="div" className="invalid-feedback" />
                            </div>
                        </div>
                        <div className="form-row">
                            <div className="form-group col-3">
                                <label>Street</label>
                                <Field name="street" type="text" className={'form-control'   (errors.street amp;amp; touched.street ? ' is-invalid' : '')} />
                                <ErrorMessage name="street" component="div" className="invalid-feedback" />
                            </div>
                            <div className="form-group col-3">
                                <label>City</label>
                                <Field name="city" type="text" className={'form-control'   (errors.city amp;amp; touched.city ? ' is-invalid' : '')} />
                                <ErrorMessage name="city" component="div" className="invalid-feedback" />
                            </div>
                            <div className="form-group col-3">
                                <label>State</label>
                                <Field name="state" type="text" className={'form-control'   (errors.state amp;amp; touched.state ? ' is-invalid' : '')} />
                                <ErrorMessage name="state" component="div" className="invalid-feedback" />
                            </div>
                            <div className="form-group col-3">
                                <label>ZipCode</label>
                                <Field name="zipCode" type="text" className={'form-control'   (errors.zipCode amp;amp; touched.zipCode ? ' is-invalid' : '')} />
                                <ErrorMessage name="zipCode" component="div" className="invalid-feedback" />
                            </div>
                        </div>
                    <h3 className="pt-3">Change Password</h3>
                    <p>Leave blank to keep the same password</p>
                    <div className="form-row">
                        <div className="form-group col">
                            <label>Password</label>
                            <Field name="password" type="password" className={'form-control'   (errors.password amp;amp; touched.password ? ' is-invalid' : '')} />
                            <ErrorMessage name="password" component="div" className="invalid-feedback" />
                        </div>
                        <div className="form-group col">
                            <label>Confirm Password</label>
                            <Field name="confirmPassword" type="password" className={'form-control'   (errors.confirmPassword amp;amp; touched.confirmPassword ? ' is-invalid' : '')} />
                            <ErrorMessage name="confirmPassword" component="div" className="invalid-feedback" />
                        </div>
                    </div>
                    <div className="form-group">
                        <button type="submit" disabled={isSubmitting} className="btn btn-primary mr-2">
                            {isSubmitting amp;amp; <span className="spinner-border spinner-border-sm mr-1"></span>}
                            Update
                        </button>
                        <button type="button" onClick={() => onDelete()} className="btn btn-danger" style={{ width: '75px' }} disabled={isDeleting}>
                            {isDeleting
                                ? <span className="spinner-border spinner-border-sm"></span>
                                : <span>Delete</span>
                            }
                        </button>
                        <Link to="." className="btn btn-link">Cancel</Link>
                    </div>
                </Form>
            )}
        </Formik>
    )
}

export { Update };
 

Комментарии:

1. Пожалуйста, приведите пример того, какой метод вы фактически вызвали, и различия между postman и react app в выходных данных. (то есть укажите фактическое значение, пожалуйста)

Ответ №1:

Понял, что модель ответа на моем asp.net веб-api не был разработан для возврата отсутствующих свойств. Спасибо за вашу заботу.