MongoDB; /delete_api_keys - mongodb

I have a case study that requires to write some endpoints to communicate with a data set stored in MongoDB.
Below is my trial to make up the query to delete multiple API keys, and it returns me TypeError: Cannot read properties for undefined (reading 'filter').
I do not understand if it's not reading an Object I call on filter, or the method .filter() itself.
I am learning; always happy to learn from constructive criticism.
Thanks in advance!
app.options("/delete_api_keys", cors());
app.delete("/delete_api_keys", auth(["admin"]), (req, res) =>{
const readings = db.collection("access")
const access_ids = req.body.keys_to_delete
.filter((access_id) => {ObjectID.isValid(access_id)})
.map((access_id) => {ObjectID.isValid(access_id)})
// Error - one of the objects I call on .filter is undefined
readings.deleteMany({ _id: { $in: access_ids } })
.then((query_result) => {
res.status(200).json({
code: 200,
message: "api keys deleted",
})
})
.catch(error => {
res.status(500).json({
code: 500,
message: "Failed to delete api key" + error,
})
})
})
Below the snapshot of Postman trying to delete multiple ObjectID using the authorised api key
[![enter image description here](https://i.stack.imgur.com/SzXbv.png)](https://i.stack.imgur.com/SzXbv.png)

Related

How to load data from remote URI with nestjs/axios properly using Observables in the correct way?

NestJs suggests to use the HttpModule imported from #nestjs/axios to perform requests to external APIs. I understand that the HttpService transforms the responses into Observables. However, it makes it hard to fetch data inside of my service that wants to fetch data from a remote service and immediately work with these data:
try {
const metaData = await this.httpService.get(tokenUri).pipe(
map((res) => res.data),
catchError((e) => {
throw new HttpException(e.statusText, e.status);
}),
);
console.log("---------------")
console.log(metaData);
console.log("---------------")
} catch (e) {
this.logger.error(`Unable to fetch MetaData from ${tokenUri}. ` + e.toString());
}
What I get is this:
---------------
Observable {
source: Observable {
source: Observable { _subscribe: [Function (anonymous)] },
operator: [Function (anonymous)]
},
operator: [Function (anonymous)]
}
---------------
The reason why I don't want to use subscribe directly after the execution of get is that this way I was not able to catch 404 errors. On the internet I found the combination of pipe and catchError in order to do so. This way I am able again to catch the errors but I don't get any data anymore.
Thus, I have still to execute subscribe to subscribe on my data.
So I came up with this:
this.logger.debug('Found Token-URI: ' + tokenUri);
try {
const metaData = await this.httpService.get(tokenUri).pipe(
map((res) => res.data),
catchError((e) => {
throw new HttpException(e.statusText, e.status);
}),
);
metaData.subscribe((x) => {
// here is my data:
console.log(x);
});
} catch (e) {
this.logger.error(`Unable to fetch MetaData from ${tokenUri}. ` + e.toString());
}
This way it works, but I am not sure if it is the right way from the nextjs/axios developers point of view.
I think in this case you can simplify your code by using an error-handler that you can provide to the .subscribe function. So instead of having to use try/catch and rethrowing the error, you could simply do:
this.logger.debug('Found Token-URI: ' + tokenUri);
const metaData$ = this.httpService.get(tokenUri).pipe(map((res) => res.data));
metaData$.subscribe(
(x) => console.log(x),
(err) => this.logger.error(`Unable to fetch MetaData from ${tokenUri}. ` + e.toString())
);
As a side note, I'd recommend reading this blog-post regarding rxjs error-handling.

Redux Toolkit - do not send request when query param is invalid

I've checked the redux toolkit docs and don't see an example of this typical use case: do not send the request of the query has an invalid param.
For example, a get request to endpoint /categories/{name} requires a name value. If name does not have a value, then the request should not be made.
const baseQuery = fetchBaseQuery({
baseUrl: Constants.PATHWAY_API_URL
});
export const pathwayApi = createApi({
reducerPath: 'pathwayApi',
baseQuery: baseQueryWithReAuth,
endpoints: builder => ({
getSubCategories: builder.query({
// NETWORK REQUEST SHOULD NOT BE MADE IF "name" param is falsy
query: name => `${Constants.PATHWAY_API.CATEGORIES_PATH_NAME}/${name}`,
}),
}),
});
I want to add this type of param validation to all my queries that require a param value or values. What's the recommended approach / pattern for handling this validation at the createApi (or possibly fetchBaseQuery) layer?
Thanks in advance!
You can actually throw an error in your query function.
export const pathwayApi = createApi({
reducerPath: "pathwayApi",
baseQuery: baseQueryWithReAuth,
endpoints: (builder) => ({
getSubCategories: builder.query({
// NETWORK REQUEST SHOULD NOT BE MADE IF "name" param is falsy
query: (name) => {
if (!name) {
throw new Error("Category name is required.");
}
return `${Constants.PATHWAY_API.CATEGORIES_PATH_NAME}/${name}`;
}
})
})
});
When this happens, your hook will have isError: true but no network request will be made. The error property of your hook will be a SerializedError object with properties name, message and stack, which you can use to display the error in your UI.
This is the same type of error object that you get if you have a TypeError somewhere in your code. Note that JavaScript errors will have error.message while API errors (FetchBaseQueryError) will have error.error.
const Category = ({ name }) => {
const { data, error, isError } = useGetSubCategoriesQuery(name);
return (
<div>
<h3>Name: "{name}"</h3>
{isError && (
<div>{error?.error ?? error?.message}</div>
)}
</div>
);
};
CodeSandbox Link

VuexFire Synchronization with bind not working

I'm currently using VuexFire to bind the Cloud Firestore to my Vuex State. I'm having some issues getting it to work, any help would be appreciated.
What I'm currently doing is the following:
Vue.js File:
methods:{
...mapActions("comments", ['bindArticleComments']),
},created(){
this.bindArticleComments()
},
actions/comments file
export const bindArticleComments = firestoreAction(({ bindFirestoreRef }) => {
return bindFirestoreRef('articleComments', collectionRef('comments'))
})
firebase services file
export const collectionRef = (collectionName) => {
return firestore().collection(collectionName)
}
What is strange about this is that I'm already doing the same procedure for a different Vuex state field. There it seems to be working without an issue. Is there anything that anyone thinks I might not be doing properly?
Strangely i got it working , although i'm struggling to understand how and why it's working.In my Vue js file i placed the this.bindArticleComments() after downloading the data and at creation.
methods:{
downloadComments(){
const { articlesCommentRef } = this.$fb
articlesCommentRef(this.loadedArticle.id).get()
.then(querySnapshot => {
this.setArticleComments(querySnapshot.docs.map((doc) => doc.data()))
this.bindArticleComments(this.loadedArticle.id)})
.catch(error => console.log("Error getting documents: ", error))
.finally(() => {this.$q.loading.hide()})
}
},
created(){
this.bindArticleComments(this.loadedArticle.id)
},
mounted(){
this.downloadComments()
}

Updating/Deleting User Profile with React on Express

I'm working on a web app with React on Express with a Postgresql database, and am working on trying to allow users the ability to delete/update their profiles. I've updated the controller, model, and routes for these changes, but I'm having an issue figuring out where to send the fetch request from the React component. Anytime I try to run a delete or an update I get the following on my terminal:
PUT /api/auth/1 400 3.468 ms - 24
--- undefined /robots.txt
I checked other threads on here and wasn't able to find how I can determine what URL I should point to for these functions. I think once I get that it should work as intended. Below are my auth routes and the functions I have set up, if anybody could suggest how I'd determine what URL to point this to I'd really appreciate it.
// handle profile update/delete
authRouter.route('/dashboard')
.get(usersController.show)
.put(usersController.update)
.delete(usersController.delete)
User Update/Delete functions:
handleUpdateSubmit(e, data, id) {
e.preventDefault()
console.log('clicked')
fetch(`/api/auth/${id}`, {
method: 'PUT',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
}).then(res => res.json())
.then(res => {
this.setState({
fireRedirect: true,
redirectPath: '/dashboard'
})
}).catch(err => console.log(err))
}
userDelete(id) {
fetch(`/api/auth/${id}`, {
method: 'DELETE',
}).then(res => res.json())
.then(res => {
this.setState({
fireRedirect: true,
redirectPath: '/'
})
}).catch(err => console.log(err))
}
Please let me know if there's any information that'd be useful for figuring this out and I'll provide it immediately, thanks!
Forgot to follow up on this, the issue was with how my functions were ordered. I moved my authrouter.Route code beneath the login/logout/register functions and it's working as expected.

Please explain this code is for Articles.events.publish

I'm looking for help to understand this code from the sample module Articles in the mean.io generated app. I can't figure out what Articles.events.publish is for.
file: packages/core/articles/server/controllers/articles.js
create: function(req, res) {
var article = new Article(req.body);
article.user = req.user;
article.save(function(err) {
if (err) {
return res.status(500).json({
error: 'Cannot save the article'
});
}
Articles.events.publish({
action: 'created',
user: {
name: req.user.name
},
url: config.hostname + '/articles/' + article._id,
name: article.title
});
res.json(article);
});
}
It's used to send data to stacksight. For detail, you can refer Module's constructor in node_modules/meanio/lib/core_modules/module/index.js, and you can find stacksight under node_modules/meanio/node_modules/stacksight.
But it will NOT send these information by default, it needs to request app id and API token from stacksight first.