Composing a Json in a Json for redux action - json

I'm trying to create an action for redux by using an import from a different file, but something isn't working. It's easier to show the code:
In Api.js:
exopt const API = {
GET_LIST: {path: '/list', method: 'GET'},
POST_LIST: {path: '/users/data', method: 'POST'}
};
In action.js:
import { API } from './Api';
export const fetchList = () => ({
type: 'API_ACTION',
payload: {
API.GET_LIST
}
)};
I would like fetchList to return the following action:
{
type: 'API_ACTION',
payload: {
path: '/exercises/list',
method: 'GET'
}
}
But instead I'm getting an error:
Syntax error: ... Unexpected token, expected , (7:9)
5 | type: 'API_ACTION',
6 | payload: {
> 7 | API.GET_LIST,
| ^
What am I doing wrong?
Appreciate the help!

You are trying to set a key on an object without specifying a value.
Your fetchList in action.js should look like this instead:
export const fetchList = () => ({
type: 'API_ACTION',
payload: {
path: API.GET_LIST.path,
method: API.GET_LIST.method,
},
)};
OR (even simpler)
export const fetchList = () => ({
type: 'API_ACTION',
payload: API.GET_LIST,
)};
There are many other ways to assign your payload (object spread, etc.), but the above should get you there.

Related

React,js + Prisma better way to update sql with a button

async function change_status(object_id:number){
const response = await fetch('/api/db', {
method: 'POST',
body: JSON.parse(`{"id":${object_id}}`)
});
if (!response.ok){
throw new Error(response.statusText);
}
return await response.json();
}
I want this button to change an int in mysql
<button onClick={() => change_status(object.id)}>
change Status
</button>
/api/db.ts
export default async function handler(req: NextApiRequest,res: NextApiResponse) {
const data = JSON.parse(req.body);
const object_id = data.id;
const find_object = await prisma.objects.findFirstOrThrow({
where: {id:object_id}
});
if (find_object.status == 0){
var change = await prisma.objects.update({
where: { id: object_id },
data: { status:1 },
})
}
else {
var change = await prisma.objects.update({
where: { id: object_id },
data: { status:0 },
})
}
res.json(change);
}
I get this error SyntaxError: Unexpected token o in JSON at position 1
Is there any better way to code the button or pass object_id without a JSON
Change your fetch to
const response = await fetch('/api/db', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ id: object_id }),
});
And in your api simply
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { id } = req.body;
...
}
I'm just gonna drop some information about Prisma when I had these kinda problems with it.
1 - don't forget to use body: JSON.stringify(), (this might be the issue here)
2 - config your header as well.
3 - I would suggest avoiding the var keyword because of some sort of things ( like hoisting).
4 - stick with Prisma documentation.they almost covered everything

Realm JS react-native can't create table from a large JSON from API with to-many relationship

In my React-Native app, using Realm DB JS, I have these three classes: TableOfProducts, Product, BarCodeProducts.
The class TableOfProducts has a list of Products and the class Product has a list of BarcodeProducts.
I model them like these:
export default class TableOfProductsSchema {
static schema = {
name: 'TabelaOfProducts',
primaryKey: 'cdTabelaPreco',
properties: {
cdTabelaPreco: {type: 'int', indexed: true},
dsTabelaPreco: 'string',
product: 'Product[]',
//I already tried like: product: {type: 'list', objectType: 'Product'}
},
};
}
export default class ProductSchema {
static schema = {
name: 'Product',
primaryKey: 'tableProduct',
properties: {
tableProduct: {type: 'string', indexed: true},
cdTableOfProduct: 'int',
idProduct: 'int',
dsProduct: 'string',
barcodeproducts: 'ProdutoCodigosBarra[]',
//I already tried like: barcodeproducts: {type: 'list', objectType: 'BarCodeProducts'}
},
};
}
export default class BarCodeProductsSchema {
static schema = {
name: 'BarCodeProducts',
primaryKey: 'idProductNrItem',
properties: {
idProductNrItem: {type: 'string', indexed: true},
idProduct: 'int',
nrBarCode: 'int',
barCodeItem: 'string',
barCodeBox: 'string',
qtBox: 'double',
},
};
}
And I have this code to get the JSON and create the data in my Realm DB:
requestTableOfPoducts = async (httpClient) => {
let itens = null;
await httpClient
.get(apiConfig.url_table_products, {
timeout: 999000,
})
.then((response) => {
itens = response.data;
})
.catch((error) => console.log(error));
console.log(itens); //runs ok and show the large JSON in console so my API is receiving itens..
return new Promise((resolve) => {
if (itens) {
const databaseOptions = {allSchemas};
Realm.open(databaseOptions).then((realm) => {
realm.write(() => {
const resolveItens = itens.tableOfProducts.map(async (obj, k) => {
return realm.create('TableOfProducts', obj, true);
});
Promise.all(resolveItens).then(() => resolve(true));
});
});
} else {
resolve(true);
}
});
};
The big problem here is: If I receive a small JSON data from API like just one TableOfProducts with a small list of Product, just 2 products, and two barcodes each product in the table BarCodeProducts my code runs ok and realm save all records correctly (1 record for TableOfProducts, 2 records for Product and 4 records for BarCodeProducts) but if I receive a large JSON (5MB), lots of records like 4 TableOfProducts and almost 50000 Products with more 20000 BarCodeProducts, with the same structure, I receive the error in console:
WARN Possible Unhandled Promise Rejection (id: 0):
TypeError: undefined is not an object (evaluating 'itens.tableOfProducts.map')
I already tried to use ".. JSON.parse(itens) .." but I receive a message that my JSON it's already a JSON parsed.
Please, please, please.. Someone Can please help me ? What could be wrong ? There is another way ?

Adding JSON data to React

I have been able to pull data from an API that I built using MongoDB and Express, but am having trouble rendering the nested data to my React component.
For example, if I type in <p>{restaurant.cuisine}</p> I am able to retrieve Burgers, American, but if I try and access {restaurant.status.delivery}, I get an error that says:
Cannot read property 'delivery' of undefined.
But if I {console.log(restaurant.status} I can see the object? I tried turning the object into an array using Object.values, but that didn't work either.
The same thing happens if I try to access the nested objects in {restaurant.images} and {restaurant.geometry}.
Here's a copy of my React hook:
import { useReducer, useEffect } from 'react';
import axios from 'axios';
const ACTIONS = {
MAKE_REQUEST: 'make-request',
GET_DATA: 'get-data',
ERROR: 'error',
};
function reducer(state, action) {
switch (action.type) {
case ACTIONS.MAKE_REQUEST:
return { loading: true, restaurant: [] };
case ACTIONS.GET_DATA:
return {
...state,
loading: false,
restaurant: action.payload.restaurant,
};
case ACTIONS.ERROR:
return {
...state,
loading: false,
error: action.payload.error,
restaurant: [],
};
default:
return state;
}
}
export default function useFetchSingleRestaurant({ id }) {
const [state, dispatch] = useReducer(reducer, {
restaurant: [],
loading: true,
});
useEffect(() => {
dispatch({ type: ACTIONS.MAKE_REQUEST });
axios
.get('http://localhost:4444/restaurants/' + id)
.then((res) => {
dispatch({
type: ACTIONS.GET_DATA,
payload: { restaurant: res.data.restaurant },
});
})
.catch((e) => {
dispatch({
type: ACTIONS.ERROR,
payload: { error: e },
});
});
}, [id]);
return state;
}
I'm accessing it in my SingleRestaurant component:
function SingleRestaurant({ match }) {
const { restaurant } = useFetchSingleRestaurant({ id: match.params.id });
return (
<p>{restaurant.status.delivery}</p>
)
}
And then here's my backend setup as well:
showRestaurant = async (req, res) => {
const restaurant = await Restaurant.findById(req.params.id)
.populate({ path: 'reviews', populate: { path: 'author' } })
.populate('author');
if (!restaurant) {
req.flash('error', 'Restaurant not found.');
return res.redirect('/restaurants');
}
res.send({ restaurant });
};
Until your server request returns restaurant it will be set as the default [] that you have set.
An empty array does not have a property of status, so hence the error.
if you change your default to null:
const [state, dispatch] = useReducer(reducer, {
restaurant: null,
loading: true,
});
And then check for a value:
function SingleRestaurant({ match }) {
const { restaurant } = useFetchSingleRestaurant({ id: match.params.id });
if (!restaurant) return 'Loading'
return (
<p>{restaurant.status.delivery}</p>
)
}
You could also pass back the loading state from your hook and then do a check on that.

How to save axios GET response data as json or as same as the arrived response

export class LoadProfile extends Component {
state = {
data: ''
}
componentDidMount() {
axios({
url: 'http://localhost:8080/profile/all',
method: 'GET',
responseType: 'json',
}).then((response) => {
// here I can iterate all response data.
response.data.forEach((d) => {
console.log("d: "+d.displayName)
});
// here I am setting sate. Later I can't iterate this data any more
this.setState(response.data);
});
}
}
Later at render method when I tried as follows:
this.state.data.forEach((el) => {
console.log("el: "+el.displayName)
})
I got error as TypeError: this.state.data.forEach is not a function
In this case, it was a JSON format. How can I save the response as it came from the server or save in JSON object so that I can iterate later?
Updated question with full code:-
export class LoadProfile extends Component {
state = {
data: ''
}
componentDidMount() {
axios({
url: 'http://localhost:8080//profile/all',
method: 'GET',
responseType: 'json',
}).then((response) => {
this.setState({data: response.data});
response.data.forEach((d) => {
console.log("d: "+d.displayName)
});
// this is fine
this.state.data.forEach((e) => {
console.log("e: "+e.displayName)
});
});
}
render() {
return (
<Table singleLine>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Id</Table.HeaderCell>
<Table.HeaderCell>Fullname</Table.HeaderCell>
<Table.HeaderCell>Birth Date</Table.HeaderCell>
<Table.HeaderCell>Gender</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
// Here error: TypeError: this.state.data.forEach is not a function
{this.state.data.forEach((el) => {
return (
<Table.Row key={el.id}>
<Table.Cell>{el.id}</Table.Cell>
<Table.Cell>
{el.displayName}
</Table.Cell>
<Table.Cell>{el.birthDate}</Table.Cell>
<Table.Cell>{el.gender}</Table.Cell>
</Table.Row>
);
})
}
</Table.Body>
</Table>
)
}
}
export default LoadProfile
So I can iterate only inside axios response method. But I can't iterate in the render method. What is wrong?
You forgot a key for the state:
this.setState({ data: response.data });
You should also set the initial state as an empty array so that the initial render can find the map function (use map, not forEach, forEach does not do anything with the return value):
state = {
data: []
}
this.state.data.map((el) => {
return (
<Table.Row key={el.id}>
<Table.Cell>{el.id}</Table.Cell>
<Table.Cell>
{el.displayName}
</Table.Cell>
<Table.Cell>{el.birthDate}</Table.Cell>
<Table.Cell>{el.gender}</Table.Cell>
</Table.Row>
);
})
do this instead
this.setState({data: response.data});

How to get the token from response?

I'm relatively new in this environment. I use "Ant design pro 4" with React and Typescript for a new project.
I call successful my IdentityServer 4 for a token for a login. I see my response in my Browser.
But how get the token in my code?
import { Reducer } from 'redux';
import { Effect } from 'dva';
export interface StateType {
status?: 'ok' | 'error';
jsonRes: string;
type?: string;
currentAuthority?: 'user' | 'guest' | 'admin';
}
export interface LoginModelType {
namespace: string;
state: StateType;
effects: {
login: Effect;
};
reducers: {
changeLoginStatus: Reducer<StateType>;
};
}
const Model: LoginModelType = {
namespace: 'login',
state: {
// status: undefined,
jsonRes: '',
},
effects: {
* login({ payload }, { call, put }) {
const response = yield call(accountLogin, payload);
yield put({
type: 'changeLoginStatus',
payload: response,
});
},
},
reducers: {
changeLoginStatus(state, { payload }) {
return {
...state,
jsonRes: payload.json, //not work
};
},
},
};
export default Model;
EDIT:
Maybe that's helpful.
export async function accountLogin(params: LoginParamsType) {
const sendData = `grant_type=password&username=${params.userName}&password=${params.password}& ........`;
const retValue = request('https://localhost:44308/connect/token', {
method: 'POST',
data: sendData,
mode: 'no-cors',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'string',
});
return retValue;
}
use payload.json().It will read the response stream to completion and parses the response as json.
I'm sure you had it figured it out by now, but here it goes anyways
reducers: {
changeLoginStatus(state, { payload }) {
return {
...state,
jsonRes: payload.access_token, //<--this should do it
};
},
when you call const response = yield call(accountLogin, payload); it gets you the output you see in debug window.
Hope that helps.