Mongoose find return an empty array but return values when i set a variable to the model - mongodb

why is the first query not working
I am using mongoose
i want to e able to check for errors during query that why I want to use the first instance
import Work from './WorkModel.js'
const response = await Work.findOne({ user: userId}).exec((err, result) => {
if (err) {
throw new Error('Try again later');
} else {
console.log(odemruId);
return result;
}
});
return response
//this return no value
const response= await Work.findOne({user: userId})
return response
//this actual works
```

Related

How to use axios to `fetch all()`

I don't understand how to use axios to fetch data from an array of urls. But I can do it with fetch. The following code works perfectly:
const url = 'https://vimeo.com/api/oembed.json?url='
async index(videoUrls = []) {
try {
const response = await Promise.all(
// videoUrls.map(videoUrl => axios.$get(`${url}${encodeURIComponent(videoUrl)}`))
videoUrls.map(videoUrl => fetch(`${url}${encodeURIComponent(videoUrl)}`))
)
const results = await Promise.all(response.map(r => r.json()));
return results;
} catch (e) {
console.error(e)
}
}
When I make a call like index(["https://vimeo.com/216850224", "https://vimeo.com/642263700"]), my console shows an array with all the video meta details vimeo has to give me. This is perfect.
But the moment I comment out the line that uses fetch and use axios, I get a CORS error.
What is the idiomatic way to fetch data from a bunch of urls in axios?
EDIT
I also tried this, but the .all() function doesn't seem to exist
async index(videoUrls = []) {
try {
const response = await axios.all(videoUrls.map(videoUrl => `${url}${encodeURIComponent(videoUrl)}`));
return response;
} catch (e) {
console.error(e)
}
}
You can easily do it like below:
(async function getAll() {
const axiosrequest1 = axios.get('https://jsonplaceholder.typicode.com/posts');
const axiosrequest2 = axios.get('https://jsonplaceholder.typicode.com/posts');
const axiosrequest3 = axios.get('https://jsonplaceholder.typicode.com/posts');
const [res1, res2, res3] = await Promise.all([axiosrequest1, axiosrequest2, axiosrequest3]);
console.log('request1', res1.data);
console.log('request2', res2.data);
console.log('request3', res3.data);
})();
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
The Axios version would be slightly different because it automatically decodes and embeds the response body into the response.data property (no need for res.json())
const baseUrl = "https://vimeo.com/api/oembed.json"
const index = async (videoUrls = []) => {
// create an array of responses and wait for them to resolve
const responses = await Promise.all(
videoUrls.map(url => axios.get(baseUrl, { params: { url } })
)
// extract the `data` properties and return them as an array
return responses.map(({ data }) => data)
}
Exactly when you extract response.data is totally up to you. It could also look like this
const index = (videoUrls = []) => Promise.all(
videoUrls.map(async (url) => (
await axios.get(baseUrl, { params: { url } })
).data)
)
FYI, your fetch() version could be a little cleaner too...
const baseUrl = "https://vimeo.com/api/oembed.json"
const index = (videoUrls = []) => Promise.all(
videoUrls.map(async (url) => {
const params = new URLSearchParams({ url })
const res = await fetch(`${baseUrl}?${params}`)
if (!res.ok) { // check for bad response
throw new Error(`${res.status}: ${await res.text()}`)
}
return res.json()
})
)

Getting a document from Firestore results in "The method 'data' was called on null. Receiver: null Tried calling: data())"

I am new to Flutter and trying to get a document from a collection; there is no error in the code but, still, the document is not obtained.
I am trying to return a variable having String in the method _onPressed() but I'm stuck at that point.
Future _onPressed() async{
var msg;
await db.collection('Messages').doc(widget.brew.id).get().then((value){
print(value.data()['Message']);
return value.data()['Message'];
});
msg = msg.data()['Message'];
return msg;
}
Wrong assignment done here. change the above code
Future _onPressed() async{
var docSnap = await db.collection('Messages').doc(widget.brew.id).get();
if (docSnap.exists) {
print('Document data: ${documentSnapshot.data()}');
return docSnap.data()['Message'];
} else {
print('Document does not exist on the database');
return docSnap.data()['Message'];
}
}
In current snippet, msg.data() throws the err as the msg was null at that time.

Future returns list before being populated

I have the following method:
Future<List<Job>> getUserJobs() async {
Query query = _firebaseDatabase
.reference()
.child("jobs")
.child(_firebaseAuth.currentUser.uid)
.orderByKey();
List<Job> userJobs = [];
if (query == null) {
return userJobs;
}
query.onValue.listen((event) {
Map<dynamic, dynamic> values = event.snapshot.value;
values.forEach((key, value) {
userJobs.add(Job.fromJson(key, Map.from(value)));
});
});
return userJobs;
}
I want to get this response in another class, however, the list returned by the above method is always []. I checked and the userJobs list is indeed populated but the return statement is executed before.
The structure of the database is:
Job collection has user IDs and for each user ID I have several job keys (each with its job data).
Try this:
Future<List<Job>> getUserJobs() async {
List<Job> userJobs = [];
// Query query =
await _firebaseDatabase
.reference()
.child("jobs")
.child(_firebaseAuth.currentUser.uid)
.once()
.orderByKey().then((result) async {
if (result.value != null) {
result.value.forEach((key, childSnapshot) {
userJobs.add(Job.fromJson(key, Map.from(childSnapshot)));
});
} else {
print(
'getUserJobs() no jobs found');
}
}).catchError((e) {
print(
'getUserJobs() error: $e');
});
// if (query == null) {
// return userJobs;
// }
// query.onValue.listen((event) {
// Map<dynamic, dynamic> values = event.snapshot.value;
// values.forEach((key, value) {
// userJobs.add(Job.fromJson(key, Map.from(value)));
// });
// });
return userJobs;
}
your loop also needs to be async..otherwise the method will return before the loop finishes, returning the empty List.. been there and got quite frustrated by this..
also always use .catchError callback.. it tells you what's going wrong ;)

How to fetch documents coming from different collections in Firestore inside a Redux Saga

I have the following saga:
export function* fetchAnalyticsData() {
try {
const data = [];
const collectionReference = firestore.collection("collection1")
const UIDSreference = yield collectionReference.get();
// getUID is a function that returns an array of UIDS of documents of collection1
const UIDS = yield call(getUID, collectionReference);
const populate = yield all(
UIDS.map((uid) => {
firestore
.collection("collection1")
.doc(uid)
.collection("collection2")
.get()
.then((response) => {
if (response.docs.length) {
response.docs.forEach((doc) => data.push(doc.data()));
console.log(data);
}
});
})
);
console.log(data);
yield put(fetchAnalyticsDataSuccess(data));
} catch (error) {
console.log(`Error in fetchAnalyticsData: ${error}`);
yield put(fetchAnalyticsDataFailure(error.message));
}
}
The inner console.log(data) prints the data array correctly filled. However, the outer console.log(data) prints an empty array. I know it's because these things are promises, but then how can I solve this issue?

Why resolving an async promise with a .map() function doesn't work for GET with parameters?

I am not sure how to express my question correctly.
Basically resolving an async promise with a .map() function works for simple get functions while it doesn't work for get functions with parameter.
Basically, in this case, router.get('/' ... the following works:
import axios from 'axios'
const url = 'http://localhost:3000/api/library/'
class libraryService {
// Get stories
static getStories () {
return new Promise(async (resolve, reject) => {
try {
const res = await axios.get(url)
const data = res.data
resolve(
data.map(story => ({
...story
}))
)
} catch (err) {
reject(err)
}
})
}
export default libraryService
While in this case, router.get('/:story_name' ..., this variation doesn't work:
class readService {
// Get story to read
static getStoryToRead (storyName) {
return new Promise(async (resolve, reject) => {
try {
const res = await axios.get(url + storyName)
const data = res.data
resolve(
data.map(selectedStory => ({
...selectedStory
}))
...
In here I get an error: 'data.map is not a function'.
Changing to data.products.map() will return an error 'Cannot read property 'map' of undefined'.
However resolving data without .map() function will work on all cases:
try {
const res = await axios.get(...)
const data = res.data
resolve(
data
)
...
Why this is happening and is it correct to just use resolve(data)?
You seem to be asking for a single story in the case that doesn't work. So instead of an array of stories, presuambly you're getting just the one story that you asked for. There's no reason to try to use map.
Minimal changes (but keep reading):
// Minimal changes, but keep reading...
static getStoryToRead (storyName) {
return new Promise(async (resolve, reject) => {
try {
const res = await axios.get(url + storyName);
resolve(res.data);
} catch (err) {
reject(err);
}
});
}
But, both of those functions demonstrate the Promise creation antipattern. You already have a promise, work with it. In this case, you'd probably do that by making the functions async:
static async getStories () {
const {data} = await axios.get(url);
return data.map(story => ({ // Why copy the story objects?
...story
}));
}
static async getStoryToRead (storyName) {
const {data} = await axios.get(url + storyName));
return data;
}
Or with non-async functions:
static getStories () {
return axios.get(url)
.then(({data}) => data.map(story => ({...story}))); // Why copy the story objects?
}
static getStoryToRead (storyName) {
return axios.get(url + storyName))
.then(({data}) => data);
}