On the API(GraphQL) - Getting Started documentation here, it says to query your data using the following:
import { API } from 'aws-amplify';
import * as queries from './graphql/queries';
// Simple query
const allTodos = await API.graphql({ query: queries.listTodos });
console.log(allTodos); // result: { "data": { "listTodos": { "items": [/* ..... */] } } }
However, when I try to apply their code to my javascript code it says that it does not recognize the word await. Online it says I can only use the await keyword inside of a async function. When I take the await keyword out, the promise from the query function does not get settled so it returns the promise first before the data.
I tried setting up an async function before, and posted a stackoverflow post about it. The solution got a little messy, and did not quite work for me. So, I am wondering what is the best way to go about querying data using Graphql? And how do I implement that?
await can be used only with in an async context, so ideally what you would have to do is the following
const allTodos = async () => {
const todos = await API.graphql({ query: queries.listTodos });
return todos
}
Related
I am having an issue when trying to retrieve data from Firestore using the Firebase JS SDK. I am receiving the following error:
TypeError: firebase_firestore__WEBPACK_IMPORTED_MODULE_3__.getDoc(...).data is not a function
I am trying to load the data using the following code:
useEffect(() => {
const getAuthorData = async () => {
setAuthorData(
await getDoc(doc(db, 'users', post.data.author)).data()
)
}
const p = getAuthorData()
console.log(p)
}, [])
I think have imported the necessary Firebase modules and initialized the app with the correct configuration. I have also checked that the getDoc function is returning a Firestore DocumentSnapshot object, but the data() method is not a function. Some data is showing behin the error
I would like to know if there is a problem with my code or if I am missing something else.
Any help would be appreciated, thanks!
The problem is that getDoc returns an object that does not have a method called data. It returns a promise. Your code right now is trying to call data() on that promise instead of first awaiting it. If you are trying to keep this at one line of code, you will have to force the await to happen first before the call to data() by using parenthesis:
(await getDoc(doc(db, 'users', post.data.author))).data()
I want to utilize mongoose's withTransaction helper particularly for its ability to automatically retry transient transaction errors. However, it seems that the withTransaction helper is incapable of returning data, which is a problem for me.
I have code that looks like:
import { startSession } from 'mongoose';
async addItem(itemData) {
const session = await startSession();
session.startTransaction();
try {
const item = await new Item({ itemData }).save({ session });
// a bunch of other async operations...
await session.commitTransaction();
session.endSession();
return item;
} catch (error) {
await session.abortTransaction();
session.endSession();
throw error;
}
}
How can I either (1) use the withTransaction helper but still have this function returning the item as it currently does, or (2) make this function automatically retry on transient transaction errors through some way other than using withTransaction.
This appears to be a known issue in the node driver. Some workarounds are provided in that ticket.
I wrote a simple helper that internally uses withTransaction to solve the problem and make transactions less verbose with mongoose.
After installing mongoose-trx you can simply do:
const transaction = require('mongoose-trx');
const [customer] = await transaction(session => Customer.create([{ name: 'Test' }], { session }));
// do whatever you need to do with the customer then return it
It supports transaction options as well, see the documentation on how to do it.
I am new to Adonis JS so extremely sorry for the Stupid Question.
I have the default setup of Adonis JS with Mysql Database and everything working.
I have created a simple usertest route where I am returning JSON of user with ID: 1.
Below is the code for the same
Route.get('/usertest', ({ response }) => {
const User = use('App/Models/User')
let data = User.query().where('id', 1)
.first()
console.log(data)
return response.status(200).json(data)
})
But it is returning and empty object
Raw Response:
{}
Console Log Statement Response:
Promise { <pending> }
I am unable to understand what am I missing here.
Note: I tried let data = User.find(1) but it did not work.
Please help me.
Thanks in advance!!!
Quick note, at least you have to execute the query asynchronously.
I mean, you have to replace:
let data = User.query().where('id', 1)
.first()
by:
let data = await User.query().where('id', 1)
.first()
Of course, this mean you have to precede the function arrow with async:
Route.get('/usertest', async ({ response }) => {
// rest of the code
let data = await User.query().where('id', 1).first()
// rest of the code
})
It is very easy to miss "await" when you start working with async-await frameworks. Just a suggestion on the query whenever you want to find one object it is good practice to use ORM's predefined function. In this case
const user = await User.findBy('id',1)
this will return the first object it finds with the given id. You will find more options and help in knex.js docs http://knexjs.org/#Builder-where
Just wanted to know how to group all of my API calls altogether in an api.js file, in my React App (just some pseudocode would work). I have read an interesting article that introduces that idea, and I feel curious because that file structure really fits my needs. How would it be?
Moreover, the author states in a comment:
I usually just put all of my API calls into that file - they're
usually small one-or-two-line functions that call out to axios, and I
just export them.
export function login(username, password) { ... } export function
getFolders() { ... } etc.
But I feel it lacks some details to reproduce it. I am new to Javascript and React. Thanks.
Say you are using axios for http calls, I guess it would be smth like this:
api.js:
import axios from 'axios';
import { resolve } from './resolve.js';
export async function login(user, pass) {
return await resolve(axios.post('http://some-api.com/auth', { user, pass }).then(res => res.data));
}
export async function getUser(id) {
return await resolve(axios.get(`http://some-api.com/users/${id}`).then(res => res.data));
}
// and so on....
And as he said on the post, If your files starts to get too big, you can create a src/api/ and create separate files like src/api/auth.js, src/api/users.js, etc..
To resolve the promises I like to use the new async/await syntax and wrap it in a little module resolver.js:
export function async resolve(promise) {
const resolved = {
data: null,
error: null
};
try {
resolved.data = await promise;
} catch(e) {
resolved.error = e;
}
return resolved;
}
And your component smth like:
// ...
componentDidMount() {
this.getUser();
}
async getUser() {
const user = await api.getUser(this.props.id);
if(user.error)
this.setState({ error: user.error });
else
this.setState({ user: user.data });
}
Again, this is something I like to do, I think the code looks clearer, keeping a synchronous structure. But I guess it's perfectly fine to resolve your promises with .then() and .catch() also.
I hope that helped!
It depends on how much API functions a project has.
I usually stick with project structure called "grouping by file type" mentioned in React official website and keep API related files in a separate directory where every file has an API functionality dedicated to a specific entity.
However, for small projects, it makes sense to keep all API functionality in one file.
Background
I am writing some asynchronous code in express. In one of my end points there I need to retrieve some data from firebase for 2 seperate things.
one posts some data
the other retrieves some data to be used in a calculation and another post.
These 2 steps are not dependent on one another but obviously the end result that should be returned is (just a success message to verify that everything was posted correctly).
Example code
await postData(request);
const data = await retrieveUnrelatedData(request);
const result = calculation(data);
await postCalculatedData(result);
In the code above postData will be holding up the other steps in the process even though the other steps (retrieveUnrelatedData & postCalculatedData) do not require the awaited result of postData.
Question
Is there a more efficient way to get the retrieveUnrelatedData to fire before the full postData promise is returned?
Yes, of course! The thing you need to know is that async/await are using Promises as their underlying technology. Bearing that in mind, here's how you do it:
const myWorkload = request => Promise.all([
postData(request),
calculateData(request)
])
const calculateData = async request => {
const data = await retrieveUnrelatedData(request);
const result = calculation(data);
return await postCalculatedData(result);
}
// Not asked for, but if you had a parent handler calling these it would look like:
const mainHandler = async (req, res) => {
const [postStatus, calculatedData] = await myWorkload(req)
// respond back with whatever?
}