why do i get an #id instead of a whole object - reactjs

Hello I am in the middle fixing a bug and whould like some outside eyes for some support.im using axios to retreive a class from my springboot tomcat server.the information is fine in the controller up to the return portion once it goes to my front end though thats where the problem occurs I get an object like this upon res.data {#id:'1'}.
my class
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIdentityInfo(generator= JSOGGenerator.class)
#Getter
#Setter
#Builder
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name = "gender")
public class Gender implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String gender;
#OneToMany(fetch=FetchType.LAZY, mappedBy="gender")
private Set<User> users;
}
the react page.
import React, { useState,memo,useEffect }from "react";
import axios from 'axios';
import JSOG from 'jsog';
import {decrypt} from "../../Util/jsogRetreival.js";
import Autocomplete from '../../Util/autocomplete';
let Gender=(props)=>{
let[gender,setgender]=useState({});
let[list,setList]=useState([]);
let[error,setError]=useState("");
let[currentValue,setCurrentValue]=useState("");
let[fullList,setFullList]=useState([]);
useEffect(() => {
let getValue="";
const fetchData = async () => {
if(props.id!==-1){
await axios.get(
'http://localhost:8080/gender/getById/'+props.id)
.then(res => {
setgender(res.data);
}).catch(
function (error) {
console.log(error);
});}
else{
await axios.get(
'http://localhost:8080/gender/getDummy')
.then(res => {
//
//where i pause my code and get the #id in res.data
//
//
let genderOf=decrypt(res.data);
let idontknow=JSOG.decode(res.data);
let fuck= JSOG.parse(idontknow);
setgender(res.data);
}).catch(
function (error) {
console.log(error);
});
}
let fromList=[];
await axios.get(
'http://localhost:8080/gender')
.then(res => {
if(res.data.length<1){
}
else{
fromList=decrypt(res.data);
}
setFullList(fromList);
}).catch(
function (error) {
console.log(error);
});
let newList=[];
let newListLink=[];
let ofList=fromList;
ofList.map((item)=>{
newList.push(item.gender);
newListLink.push(item.link);
});
setList(newList);
}
// call the function
fetchData();
});
let onChange=(value,tag)=>{
if(tag==='gender'){
setCurrentValue(value);
let newList=[];
fullList.map((item)=>{
if(item.gender.startsWith(value)){
newList.push(newList.push(item.gender));
}
});
setList(newList);
}
}
let handleSubmit=async(event) => {
event.preventDefault();
await axios.post(
'http://localhost:8080/gender',gender)
.then(res => {
let errors=decrypt(res.data);
setError(errors.genderError);
}).catch(
function (error) {
console.log(error);
});
};
return (<div>
<form action={handleSubmit} >
genderName:<Autocomplete list={list} onChangeValue={onChange}/>
<div>{error}</div>
<input type="submit" value="Submit" />
</form>
</div>);
}
export default Gender;

Related

How to test public functions in Typescript with react-testing-library?

I'm having below setup in my project, whenever I extends the httpService and use the 'this.instance' in any service I'm getting the error.
If I use axios.get directly without any interceptors in my service files its working fine.
Im new to the unit testing and badly stuck with this. Please share your comments below. It'll be really helpful.
httpClient.ts
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
import { DEFAULT_HEADERS, HOST } from './ApiHelper';
export abstract class HttpService {
protected readonly instance: AxiosInstance;
public constructor(requestConfig: AxiosRequestConfig) {
this.instance = axios.create(requestConfig);
this.instance.interceptors.request.use((request) => {
request.baseURL = HOST;
request.headers = { ...DEFAULT_HEADERS };
return request;
});
this.instance.interceptors.response.use(
(response) =>
response,
(error) =>
new Promise((resolve, reject) => {
reject(error.response);
}),
);
}
}
export default HttpService;
someService.ts
import HttpService from './HttpService';
const warningListUrl = 'some/url';
class SomeService extends HttpService {
public constructor() {
super({
});
}
public async getSomething(params: any) {
this.instance({
method: 'GET',
url: warningListUrl,
params,
}).then((res) =>
res.data);
}
}
export default SomeService;
ReactComponent.tsx
const fetchList = async () => {
try {
setIsLoading(true);
const someService = new SomeService();
const response: any = await someService.getSomething({});
setWarnings(response.content);
setTotalPages(response.totalPages);
} catch (error) {
console.log(error);
} finally { setIsLoading(false); }
};
useEffect(() => {
fetchList();
}, []);
ReactComponent.test.tsx
jest.mock('../../services/SomeService');
const someService = new SomeService();
describe('page tests', () => {
test('page renders without crashing', async () => {
(someService.getWarningList as jest.Mock).mockResolvedValue(someMatchingData);
await act(async () => {
render(<ReactComponent />);
});
const text = screen.getByText('Warning 1');
expect(text).toBeInTheDocument();
});
}
Error:
TestingLibraryElementError: Unable to find an element with the text: Warning 1. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
render(<Warning />);
});
-> const text = screen.getByText('Warning 1');
expect(text).toBeInTheDocument();
});
You could use requireActual if you need to mock only specific methods.
jest.mock('../../services/SomeService', ()=> {
return {
...jest.requireActual('../../services/SomeService'),
getWarningList: new Promise.resolve(someMatchingData)
}
})
How about mocking a module like this?
Accessing methods through 'prototype' saved my day.
(someService.prototype.getWarningList as jest.Mock).mockResolvedValue(someMatchingData);
just adding it above the test description saved me.

How to make a PATCH request in ReactJS ? (with Nestjs)

nestjs controller.ts
#Patch(':id')
async updateProduct(
#Param('id') addrId: string,
#Body('billingAddr') addrBilling: boolean,
#Body('shippingAddr') addrShipping: boolean,
) {
await this.addrService.updateProduct(addrId, addrBilling, addrShipping);
return null;
}
nestjs service.ts
async updateProduct(
addressId: string,
addrBilling: boolean,
addrShipping: boolean,
) {
const updatedProduct = await this.findAddress(addressId);
if (addrBilling) {
updatedProduct.billingAddr = addrBilling;
}
if (addrShipping) {
updatedProduct.shippingAddr = addrShipping;
}
updatedProduct.save();
}
there is no problem here. I can patch in localhost:8000/address/addressid in postman and change billingAddr to true or false.the backend is working properly.
how can i call react with axios?
page.js
const ChangeBillingAddress = async (param,param2) => {
try {
await authService.setBilling(param,param2).then(
() => {
window.location.reload();
},
(error) => {
console.log(error);
}
);
}
catch (err) {
console.log(err);
}
}
return....
<Button size='sm' variant={data.billingAddr === true ? ("outline-secondary") : ("info")} onClick={() => ChangeBillingAddress (data._id,data.billingAddr)}>
auth.service.js
const setBilling = async (param,param2) => {
let adressid = `${param}`;
const url = `http://localhost:8001/address/`+ adressid ;
return axios.patch(url,param, param2).then((response) => {
if (response.data.token) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
})
}
I have to make sure the parameters are the billlingddress field and change it to true.
I can't make any changes when react button click
Since patch method is working fine in postman, and server is also working fine, here's a tip for frontend debugging
Hard code url id and replace param with hard coded values too:
const setBilling = async (param,param2) => {
// let adressid = `${param}`;
const url = `http://localhost:8001/address/123`; // hard code a addressid
return axios.patch(url,param, param2).then((response) => { // hard code params too
console.log(response); // see console result
if (response.data.token) {
// localStorage.setItem("user", JSON.stringify(response.data));
}
// return response.data;
})
}
now it worked correctly
#Patch('/:id')
async updateProduct(
#Param('id') addrId: string,
#Body('billingAddr') addrBilling: boolean,
) {
await this.addrService.updateProduct(addrId, addrBilling);
return null;
}
const ChangeBillingAddress = async (param) => {
try {
await authService.setBilling(param,true).then(
() => {
window.location.reload();
},
(error) => {
console.log(error);
}
);
}
catch (err) {
console.log(err);
}
}
const setBilling= async (param,param2) => {
let id = `${param}`;
const url = `http://localhost:8001/address/`+ id;
return axios.patch(url,{billingAddr: param2}).then((response) => {
if (response.data.token) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
})
}

Fetch data after login React MobX

I'm using .Net with React.
And after I login I want to load data otherwise it shouldn't show the user.
My ProductsController:
[Authorize]
[HttpGet]
public async Task<ActionResult<List<Product>>> GetProducts()
{
return await Mediator.Send(new List.Query());
}
In my MobX userStore login method:
login = async (creds: UserFormValues) => {
try {
const user = await agent.Account.login(creds);
store.commonStore.setToken(user.token);
runInAction(() => (this.user = user));
history.push('/products');
} catch (error) {
throw error;
}
};
The method to load data in productStore:
loadProducts = async () => {
this.loadingInitial = true;
try {
const products = await agent.Products.list();
products.forEach((product) => {
this.setProduct(product);
});
} catch (error) {
console.log(error);
}
};
And in my ProductsList.tsx:
<tbody>
{productsArray.map((product: any) => (
<tr key={product.id}>
<td>{product.id}</td>
<td>{product.title}</td>
</tr>
))}
</tbody>
I want to load the data after user is logged in but can't seem to work it out.

How to call get api in react js using ID?

I am trying to fetch customer record using ID but it gives me error 404 and even if I try using like "https://localhost:44387/api/Customers/5" in browser it gives result only for ID 5 and below error message for other id
{
"type":"https://tools.ietf.org/html/rfc7231#section-6.5.4",
"title":"Not Found",
"status":404,
"traceId":"|a1f6c563-4f8db349ec6c707f."
}
this is the call Customer. If I click on any edit it passes the ID but when It try to fetch the specific user data it gives me error. In onEditCustomer
import React from 'react';
import { Table, Button } from 'semantic-ui-react';
import AddCustomer from './AddCustomer';
export default class Customer extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
formClose:false,
isAddCustomer:false,
isEditCustomer:false,
singleCustomer:{},
users: []
}
}
//fetch data
componentDidMount() {
const customerApi = 'https://localhost:44387/api/Customers';
const myHeader = new Headers();
myHeader.append('Content-type', 'application/json');
myHeader.append('Accept', 'application/json');
myHeader.append('Origin','https://localhost:44387');
const options = {
method: 'GET',
myHeader
};
fetch(customerApi, options)
.then(res => res.json())
.then(
(result) => {
this.setState({
users: result,
isLoaded: true
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
//close form
closeForm = event => {
this.props.closeCreateForm();
}
//New Customer record
onAddFormSubmit = data => {
const customerApi = 'https://localhost:44387/api/Customers';
const myHeader = new Headers({
'Accept':'application/json',
'Content-type':'application/json'
});
fetch(customerApi,{
method:'post',
headers:myHeader,
body:JSON.stringify(data)
})
.then(res => res.json())
.then(
(result) => {
console.log("Customer add result");
console.log(result);
this.setState({})
},(error) => {
this.setState({ error });
}
)
}
//Edit customer record
onEditCustomer = custId => {
const customerApi = 'https://localhost:44387/api/Customers/';
const customerRecord = new FormData();
customerRecord.append("customerId", custId );
const myHeader = new Headers({
'Accept':'application/json',
'Content-type':'application/json; charset=utf-8'
});
fetch(customerApi,{
method:'POST',
headers:myHeader,
body:customerRecord
})
.then(res => res.json())
.then(
(result) => {
this.setState({
singleCustomer:result,
isEditCustomer:true,
isAddCustomer:true
})
},(error) => {
this.setState({ error });
}
)
}
render() {
const { users } = this.state;
let customerForm;
if (this.state.isEditCustomer || this.state.isAddCustomer){
customerForm = <AddCustomer onAddFormSubmit = {this.onAddFormSubmit} singleCustomer = {this.state.singleCustomer}/>
}
return (
<div>
<Table celled textAlign='center'>
<Table.Header>
<Table.Row>
<Table.HeaderCell>ID</Table.HeaderCell>
<Table.HeaderCell>Name</Table.HeaderCell>
<Table.HeaderCell>Address</Table.HeaderCell>
<Table.HeaderCell>Action</Table.HeaderCell>
<Table.HeaderCell>Action</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body >
{
users.map(user => (
<Table.Row key={user.customerId}>
<Table.Cell>{user.customerId}</Table.Cell>
<Table.Cell>{user.name}</Table.Cell>
<Table.Cell>{user.address}</Table.Cell>
<Table.Cell>
<Button color='blue' onClick = {()=>this.onEditCustomer(user.customerId)}>Edit</Button>
</Table.Cell>
<Table.Cell>
<Button color='red'>Delete</Button>
</Table.Cell>
</Table.Row>
))
}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan='5'>
No of Pages
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
</div>
)
}
}
Here is ASP.NET Core controller for API
namespace CRUDReact.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CustomersController : ControllerBase
{
private readonly DataBaseContext _context;
public CustomersController(DataBaseContext context)
{
_context = context;
}
// GET: api/Customers
[HttpGet]
public async Task<ActionResult<IEnumerable<Customer>>> GetCustomer()
{
return await _context.Customer.ToListAsync();
}
// GET: api/Customers/5
[HttpGet("{id}")]
public async Task<ActionResult<Customer>> GetCustomer(int id)
{
var customer = await _context.Customer.FindAsync(id);
if (customer == null)
{
return NotFound();
}
return customer;
}
// PUT: api/Customers/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPut("{id}")]
public async Task<IActionResult> PutCustomer(int id, Customer customer)
{
customer.CustomerId = id;
_context.Entry(customer).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!CustomerExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/Customers
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPost]
public async Task<ActionResult<Customer>> PostCustomer(Customer customer)
{
_context.Customer.Add(customer);
await _context.SaveChangesAsync();
return CreatedAtAction("GetCustomer", new { id = customer.CustomerId }, customer);
}
// DELETE: api/Customers/5
[HttpDelete("{id}")]
public async Task<ActionResult<Customer>> DeleteCustomer(int id)
{
var customer = await _context.Customer.FindAsync(id);
if (customer == null)
{
return NotFound();
}
_context.Customer.Remove(customer);
await _context.SaveChangesAsync();
return customer;
}
private bool CustomerExists(int id)
{
return _context.Customer.Any(e => e.CustomerId == id);
}
}
}
Perhaps you should update your endpoint to append customer ID?
const customerApi = 'https://localhost:44387/api/Customers/' + custId;

I am returning an array in the contract. How do I accept it in my app.js using react and web3?

I have used truffle unbox react.
My contract -
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract SimpleStorage {
enum Status { NotExist, Created, InTransit, PaidFor, Completed }
struct Property {
Status state;
uint price;
address currOwner;
}
Property[] public arr;
mapping (address => uint) balances;
Property public house;
function registerProperty(uint _price) public {
house = Property(Status.Created, _price,msg.sender);
//emit NewProperty(msg.sender, _price);
}
function get()public returns(Status, uint , address){
return (house.state, house. price , house.currOwner);
}
}
App.js -
import React, { Component } from "react";
import SimpleStorageContract from "./contracts/SimpleStorage.json";
import getWeb3 from "./utils/getWeb3";
import "./App.css";
class App extends Component {
state = { storageValue:"", web3: null, accounts: null, contract: null,newValue:"" };
componentDidMount = async () => {
try {
this.handleChange=this.handleChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
// Get network provider and web3 instance.
const web3 = await getWeb3();
// Use web3 to get the user's accounts.
const accounts = await web3.eth.getAccounts();
// Get the contract instance.
const networkId = await web3.eth.net.getId();
const deployedNetwork = SimpleStorageContract.networks[networkId];
const instance = new web3.eth.Contract(
SimpleStorageContract.abi,
deployedNetwork && deployedNetwork.address,
);
// Set web3, accounts, and contract to the state, and then proceed with an
// example of interacting with the contract's methods.
this.setState({ web3, accounts, contract: instance }, this.runExample);
} catch (error) {
// Catch any errors for any of the above operations.
alert(
`Failed to load web3, accounts, or contract. Check console for details.`,
);
console.error(error);
}
};
handleChange(event){
this.setState({newValue: event.target.value });
}
handleSubmit = async event => {
const { contract, accounts } = this.state;
event.preventDefault();
await contract.methods.registerProperty(this.state.newValue).send({ from: accounts[0] });
const {response} = await contract.methods.get().call();
this.setState({ storageValue: response });
}
runExample = async () => {
const {contract } = this.state;
// Stores a given value, 5 by default.
// await contract.methods.set("").send({ from: accounts[0] });
// Get the value from the contract to prove it worked.
const response = await contract.methods.get().call();
// Update state with the result.
this.setState({ storageValue: response});
};
render() {
//if (!this.state.web3) {
// return <div>Loading Web3, accounts, and contract...</div>;
//}
return (
<div className="App">
<h1>Good to Go!</h1>
<div>The stored value is: {this.state.storageValue}</div>
<form onSubmit={this.handleSubmit}>
<input type="text" value ={this.state.newValue} onChange={this.handleChange.bind(this)} />
<input type="submit" value="submit" />
</form>
</div>
);
}
}
export default App;
If I return only a single value the code runs perfectly but for an array if I have to use a map, how do I do it? It is an array of structs, I have don't return as an array also, and return multiple values still it shows an error.

Resources