eslint arrow-body-style issue - javascript

I configured my eslint so it uses the arrow-body-style as needed:
arrow-body-style: ["error", "as-needed"]
But I'm getting an error below for some reason.
router.get('/', (req, res, next) => {
Product.find({})
.select('name price _id')
.then(items => {
const response = {
count: items.length,
products: items.map(item => { // eslint points the error here
return {
name: item.name,
price: item.price,
_id: item._id,
request: {
type: 'GET',
url: `http://localhost:3000/products/${item._id}`
}
};
})
};
res.status(200).json(response);
})
.catch(error => {
console.log(error);
res.status(500).json({ message: 'Server error' });
});
});
How exactly am I supposed to re-write my code?

Using arrow-body-style: ["error", "as-needed"] configuration is redundant as it is the default behaviour. You don't need setting it again as it is already set as the default form.
as-needed
Examples of incorrect code for this rule with the default "as-needed" option:
/*eslint arrow-body-style: ["error", "as-needed"]*/
/*eslint-env es6*/
let foo = () => {
return 0;
};
let foo = () => {
return {
bar: {
foo: 1,
bar: 2,
}
};
};
Examples of correct code for this rule with the default "as-needed" option:
/*eslint arrow-body-style: ["error", "as-needed"]*/
/*eslint-env es6*/
let foo = () => 0;
let foo = (retv, name) => {
retv[name] = true;
return retv;
};
let foo = () => ({
bar: {
foo: 1,
bar: 2,
}
});
let foo = () => { bar(); };
let foo = () => {};
let foo = () => { /* do nothing */ };
let foo = () => {
// do nothing.
};
let foo = () => ({ bar: 0 });
ESLint Docs on arrow-body
In your code sample it should be this way:
router.get('/', (req, res, next) => {
Product.find({})
.select('name price _id')
.then(items => {
const response = {
count: items.length,
products: items.map(item => ({ // no more errors
name: item.name,
price: item.price,
_id: item._id,
request: {
type: 'GET',
url: `http://localhost:3000/products/${item._id}`
});
})
};
res.status(200).json(response);
})
.catch(error => {
console.log(error);
res.status(500).json({ message: 'Server error' });
});
});
Since you're simply returning a plain object, there's no need for the extra pair of braces and return. Wrapping the object in parentheses ({ ... }), works as that is implicitly returned.

Try to omit return keyword and wrap the result into parenthesis:
products: items.map(item => ({
name: item.name,
price: item.price,
_id: item._id,
request: {
type: 'GET',
url: `http://localhost:3000/products/${item._id}`
}
}))

Related

Cannot destructure property 'data' of '(intermediate value)' as it is undefined -problem in jest

I write test in Jest for my app trying to test if the data downloads correctly from the api. These are the data of the movies.
export const programsMock: FetchProgramsParameters = {
meta: {
status: 200,
pagination: {
page: 1,
perPage: 15,
hasNext: true,
},
},
data: [
{
id: "1",
title: "No Abras la Puerta",
genres: ["Drama", "Komedi", "Komedi", "Drama", "Romantik"],
imdb: {
rating: "7.1",
},
playProviders: [],
},
]}
jest.mock("./server/services/api");
render(<App />);
const fetchProgramsMocked = jest.mocked(fetchAllProgramsParameters);
describe("GET ", () => {
it("responds with 200", async () => {
fetchProgramsMocked.mockResolvedValueOnce(programsMock);
expect(fetchProgramsMocked).toHaveBeenCalledTimes(1);
expect(screen.getByText(/No Abras la Puerta/i)).toBeTruthy();
});
But I get error in getData: Cannot destructure property 'data' of '(intermediate value)' as it is undefined.
getData:
export const getAllPrograms = async (category: string) => {
const { data } = await fetchAllProgramsParameters(category);
const programs: TVProgram[] = data.map((program) => {
return {
id: program.id,
title: program.title,
imageLandscape: program.imageLandscape,
genres: program.genres,
playProviders: program.playProviders,
imdb: program.imdb,
};
});
return programs;
};
async function fetchApi<T>(pathname: string, filter?: string) {
const response = await fetch(`${pathname}${filter}`);
if (response.status === 404) {
throw new NotFoundError();
}
if (response.status >= 400) {
throw new HttpError("Bad response", response.status);
}
return response.json() as Promise<T>;
}
async function fetchAllProgramsParameters(category: string) {
return fetchApi<FetchProgramsParameters>(
API_URL,
["orderBy=views", "programType=" + category].join("&")
);
}
Please help how to solve it

proper use of onCompleted for GraphQL mutations

I want to run the query first. The query returns an id which is then required for the mutation. Currently, there's an issue with the order of how both things run from the handleSubmit(). If the mutation is successful, the console should print console.log('Checking');but that does not happen. The only output I get on the console is What's the Idand the value is probably something that was stored in one of my previous attempts. If the id was derived from this particular round of query, I would have seen Workingon the log, but that doesn't happen either.
const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery, {
variables: {
where: { email: friendEmail.toLocaleLowerCase() },
},
onCompleted: () => getFriendId(),
});
const [
createUserRelationMutation,
{
data: addingFriendData,
loading: addingFriendLoading,
error: addingFriendError,
},
] = useCreateUserRelationMutation({
variables: {
input: {
relatedUserId: Number(id),
type: RelationType.Friend,
userId: 5,
},
},
onCompleted: () => addFriend(),
});
const getFriendId = () => {
console.log('Working');
if (data) {
console.log(data);
if (data.users.nodes.length == 0) {
console.log('No user');
setErrorMessage('User Not Found');
} else {
console.log('ID', data.users.nodes[0].id);
setId(data.users.nodes[0].id);
}
} else {
if (error) {
setErrorMessage(error.message);
}
}
};
const addFriend = () => {
console.log('Whats the Id', Number(id));
if (addingFriendData) {
console.log('Checking');
console.log(addingFriendData);
}
if (addingFriendError) {
console.log('errorFriend', addingFriendError.message);
setErrorMessage(addingFriendError.message);
}
};
const handleSubmit = () => {
loadUsers();
createUserRelationMutation();
};
Before this, I was trying this:
const [id, setId] = useState('');
const [friendEmail, setFriendEmail] = useState('');
const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery);
const [createUserRelationMutation, { data: addingFriendData, loading: addingFriendLoading, error: addingFriendError }] = useCreateUserRelationMutation();
const getFriendId = () => {
console.log('Email', friendEmail.toLocaleLowerCase());
loadUsers({
variables: {
where: { email: friendEmail.toLocaleLowerCase() },
},
});
if (data) {
console.log('ID', data.users.nodes[0].id);
setId(data.users.nodes[0].id);
}
addFriend();
};
const addFriend = () => {
console.log('Whats the Id', Number(id));
createUserRelationMutation({
variables: {
input: {relatedUserId: Number(id), type: RelationType.Friend, userId: 7 }
},
});
if (addingFriendData){
console.log('Checking')
console.log(data);
}
if(addingFriendError){
console.log('errorFriend', addingFriendError.message);
setErrorMessage(addingFriendError.message);
}
}
const handleSubmit = () =>
{getFriendId();};
However, in this case, the values of the id & other states weren't being updated timely. I was running a graphql query inside getFriendId()that returns an id, followed by a mutation (inside addFriend(), which uses the id, along with an input (email) that the user types in. The problem is that on the first attempt, the mutation works fine and with correct values. However, when I change the email address on the input and run the query/mutation again, the values from my previous attempt are being used.
In the second attempt, the mutation was still using the id that we got in the first attempt.
Edit:
onCompleted: (data) => getFriendId(data),
const getFriendId = (data: any) => {
console.log('Working');
if (data) {
console.log(data);
if (data.users.nodes.length == 0) {
console.log('No user');
setErrorMessage('User Not Found');
} else {
console.log('ID', data.users.nodes[0].id);
setId(data.users.nodes[0].id);
}
Updated Code:
const [friendEmail, setFriendEmail] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery);
const [
createUserRelationMutation,
{
data: addingFriendData,
loading: addingFriendLoading,
error: addingFriendError,
},
] = useCreateUserRelationMutation();
const getFriendId = () => {
console.log('Email', friendEmail.toLocaleLowerCase());
loadUsers({
variables: {
where: { email: friendEmail.toLocaleLowerCase() },
},
});
if (data) {
if (data.users.nodes.length == 0) {
console.log('No user');
setErrorMessage('User Not Found');
} else {
console.log('ID', data.users.nodes[0].id);
setId(data.users.nodes[0].id);
addFriend(data.users.nodes[0].id);
}
} else {
console.log('No data');
if (error) {
setErrorMessage(error.message);
}
}
//addFriend();
};
const addFriend = (idd: any) => {
console.log('Whats the Id', Number(idd));
createUserRelationMutation({
variables: {
input: {relatedUserId: Number(idd), type: RelationType.Friend, userId: 9 }
},
});
if (addingFriendData){
console.log('Checking')
console.log(data);
}
if(addingFriendError){
console.log('errorFriend', addingFriendError.message);
setErrorMessage(addingFriendError.message);
}
}
const handleSubmit = () =>
{
getFriendId();
};
You don’t need state to store ID, instead pass the Id to addFriend method like show below
const [friendEmail, setFriendEmail] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const _onLoadUserError = React.useCallback((error: ApolloError) => {
setErrorMessage(error.message);
}, []);
const [
createUserRelationMutation,
{
data: addingFriendData,
loading: addingFriendLoading,
error: addingFriendError,
called: isMutationCalled
},
] = useCreateUserRelationMutation();
const addFriend = React.useCallback((idd: Number) => {
console.log('Whats the Id', idd);
createUserRelationMutation({
variables: {
input: { relatedUserId: idd, type: RelationType.Friend, userId: 9 }
}
});
}, [createUserRelationMutation]);
const getFriendId = React.useCallback((data: any) => {
console.log('Email', friendEmail.toLocaleLowerCase());
if (data) {
if (data.users.nodes.length == 0) {
console.log('No user');
setErrorMessage('User Not Found');
} else {
console.log('ID', data.users.nodes[0].id);
addFriend(Number(data.users.nodes[0].id));
}
}
}, [friendEmail, addFriend]);
const [loadUsers] = useLazyQuery(LoadUsersQuery, {
onCompleted: getFriendId,
onError: _onLoadUserError
});
const handleSubmit = React.useCallback(() => {
loadUsers({
variables: {
where: { email: friendEmail.toLocaleLowerCase() },
}
});
}, [loadUsers, friendEmail]);
if (!addingFriendLoading && isMutationCalled) {
if (addingFriendData) {
console.log('Checking')
console.log(data);
}
if (addingFriendError) {
console.log('errorFriend', addingFriendError.message);
setErrorMessage(addingFriendError.message);
}
}
Update
I have updated the above code, please refer to it. I'm assuming useCreateUserRelationMutation does not accept options as argument, if it accepts option then you could use onCompleted and onError just like loadUsers query.

How to use DataLoader with Mongoose

I'm trying to build the following use case of DataLoader together with Mongoose:
export const PurchaseOrderType = new GraphQLObjectType({
name: "PurchaseOrder",
description: "PurchaseOrder",
interfaces: () => [NodeInterface],
isTypeOf: value => value instanceof PurchaseOrderModel,
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLID),
resolve: obj => dbIdToNodeId(obj._id, "PurchaseOrder")
},
name: {
type: new GraphQLNonNull(GraphQLString)
},
customer: {
type: CustomerType,
resolve: (source, args, context) => {
return context.customerLoader.load(source.customer_id);
}
}
})
});
export default () => {
return graphqlHTTP((req, res, graphQLParams) => {
return {
schema: schema,
graphiql: true,
pretty: true,
context: {
customerLoader: customerGetByIdsLoader()
},
formatError: error => ({
message: error.message,
locations: error.locations,
stack: error.stack,
path: error.path
})
};
});
};
export const customerGetByIdsLoader = () =>
new DataLoader(ids => {
return customerGetByIds(ids);
});
export const customerGetByIds = async ids => {
let result = await Customer.find({ _id: { $in: ids }, deletedAt: null }).exec();
let rows = ids.map(id => {
let found = result.find(item => {
return item.id.equals(id);
});
return found ? found : null; << === found always undefined
});
return rows;
};
I'm facing the following problems when loading several PurchaseOrders:
A single customer_id is being called more than once in the ids parameter of the DataLoader. So an example id 5cee853eae92f6021f297f45 is being called on several requests to my loader, in successive calls. That suggests that the cache is not working properly.
My found variable when processing the read result is always being set to false, even comparing the right ids.
You can use findOne
export const customerGetByIds = async ids => {
let result = await Customer.find({ _id: { $in: ids }, deletedAt: null }).exec();
const rows = []
let promiseAll = ids.map(async (id) => {
let found = result.filter(item => item.id.toString() === id.toSring());
if(found) {
rows.push(found[0])
return found[0]
}
return null;
});
await Promise.all(promiseAll);
return rows;
};

While using redux, 'payload' property is undefined when the getter method is being invoked

I'm unable to access my property defined as a getter.
I've console.logged all segments feeding that property, so i think the getter definition is wrong.
export const messageThreadChecker = (_uid) => (dispatch, getState) => {
chatRef.child(_uid).on('value', snap => {
!snap.exists() && dispatch(finishThreadCheck(false));
dispatch(finishThreadCheck(!snap.val().isActivated ? {
status: 'pending'
} : {
status: 'active',
get payload() {
chatRef.child(snap.val()._tid + '/messages/').orderByKey().limitToLast(1).once('value', (_message) => {
var _lastRef = _.values(_message.val())[0]._id;
userRef.child(snap.val().provider.id)
.once('value').then((snapshot) => {
return {
correspondent: {
name: snapshot.val().name,
avatar: snapshot.val().avatar
},
threadId: snapshot.val()._tid,
lastRef: _lastRef,
}
})
})
}
}))
})
};
Upon attempting to access the payload property, I'm getting the following:
{status:'active',payload:undefined}
If a getter doesn't return anything than its property value is undefined.
Your payload getter function doesn't return anything because it has no return statement. Maybe you wanted this?
export const messageThreadChecker = (_uid) => (dispatch, getState) => {
chatRef.child(_uid).on('value', snap => {
!snap.exists() && dispatch(finishThreadCheck(false));
dispatch(finishThreadCheck(!snap.val().isActivated ? {
status: 'pending'
} : {
status: 'active',
get payload() {
return chatRef.child(snap.val()._tid + '/messages/').orderByKey().limitToLast(1).once('value', (_message) => {
var _lastRef = _.values(_message.val())[0]._id;
userRef.child(snap.val().provider.id)
.once('value').then((snapshot) => {
return {
correspondent: {
name: snapshot.val().name,
avatar: snapshot.val().avatar
},
threadId: snapshot.val()._tid,
lastRef: _lastRef,
}
})
})
}
}))
})
};

Populate array objects from result inside a Function [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 5 years ago.
I need to call the result(array from a function) Called outside the function
My Code look likes this
import axios from 'axios'
var cheats
(() => {
axios.get('api/cheats/getcheaternames')
.then((response) => {
cheats = response.data
console.log(cheats, 'yeah')//results[Good, Bad]
return cheats
})
.catch((error) => {
console.log(error, 'err')
})
})()
const it = [
{
name: ...
}
]
This is how I hardcode the result,
const it = [
{
name: 'Good'
},
{
name: 'Bad'
},
{
name: 'Handsome'
}
]
Any idea to dynamically populate the it variable?
Update
I have no enough reputation to answer my own question, here it is how I refactor my code to make it work
import axios from 'axios'
var cheats
var it = []
let myFirstPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(axios.get('api/cheats/getcheaternames')
.then((response) => {
cheats = response.data
return cheats
})
.catch((error) => {
console.log(error, 'err')
}))
}, 250)
})
myFirstPromise.then((successMessage) => {
// for (var i = 0; i < successMessage.length; i++) {
// it.push({name: i})
// }
for (const value of successMessage) {
it.push({name: value})
}
})
export default {
items: [
{
name: 'Dashboard',
url: '/dashboard',
icon: 'icon-speedometer',
badge: {
variant: 'primary',
text: 'Cheaters'
}
},
{
title: true,
name: 'Elements',
class: '',
wrapper: {
element: '',
attributes: {}
}
},
{
name: 'Cheats',
url: '/components',
icon: 'icon-puzzle',
children: it
},
{
name: 'Angular Version',
url: 'https://angular.herokuapp.com/',
icon: 'icon-cloud-download',
class: 'mt-auto',
variant: 'success'
}
]
}
Any idea to make this code better is appreciated. Am I missing something or am I doing right with this code?
Not entirely clear what you're asking, but if you're asking how to change the items variable, change it to have let instead of const and change your code to:
.then((response) => {
cheats = response.data;
console.log(cheats, 'yeah')//results[Good, Bad]
items = response.data.map(item => ({ name: item }));
return cheats
})

Categories