I am trying to set a route. I followed a tutorial.
Everything is happening in a folder inside the api folder.
Route folder contains post.js file :
'use strict';
/**
* post router.
*/
const { createCoreRouter } = require('#strapi/strapi').factories;
module.exports = createCoreRouter('api::post.post', {
method: 'GET',
path: '/api/posts/:id/comments',
handler: 'posts.comments'
});
Controllers folder contains an other post.js file :
'use strict';
/**
* post controller
*/
const { createCoreController } = require('#strapi/strapi').factories;
module.exports = createCoreController('api::post.post', ({strapi}) => ({
comments: async (ctx) => {
return "Hello"
}
}));
Finally, when I tested URL : http://localhost:1337/api/posts/:id/comments; I have :
{
"data": null,
"error": {
"status": 404,
"name": "NotFoundError",
"message": "Not Found",
"details": {}
}
}
What did I do wrong ? Is something missing ?
I think the url should be like http://localhost:1337/api/posts/1/comments and not http://localhost:1337/api/posts/:id/comments. Means url should provide actual id instead of ':id'. Try it.
Related
Hello i am using the latest version of express-validator to validate my requests body, the problem is when i am using notEmpty() or not().isEmpty() it always shows an error with prsonalized message i putted "text field is required" even when the text field is not empty
this is my validator.js file
import { body } from "express-validator";
export const checkPost = () => {
return [
body("text")
.trim()
.notEmpty()
.withMessage("text field is required")
];
};
this is my route.js :
router.post("/", checkPost(), uploadImg, createPost);
and this is my controller.js
export const createPost = async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.json({ errors: errors.array() });
} ....
this is the response i get :
{
"errors": [
{
"value": "",
"msg": "text field is required",
"param": "text",
"location": "body"
}
]
}
Can anyone help me please ?
You will need a body parser middleware set up before handling the body fields. For instance, try setting your route like this (if you're sending the body as json):
router.post("/", express.json(), checkPost(), uploadImg, createPost);
After many hours of search i found that the express-validator middleware should be called after the usage of multer so changing my route this way solved the problem
router.post("/",uploadImg, checkPost(), createPost);
I have a locally hosted mongodb database with mongoose, express, axios, and a Vue front end. Right now I'm trying to access a single object from an exported array, but I'm missing the mark and getting "undefined" as the result.
vue.config.js:
module.exports = {
devServer: {
proxy: 'http://localhost:3000',
}
}
here's the front end Vue script meant to use the objects:
import axios from 'axios';
export default {
name: 'Game',
data () {
return {
pages: [],
currentPage: {},
pageTitle: "",
pageText: "",
options: [],
}
},
created () {
this.getPages();
},
methods: {
async getPages() {
try {
let res = await axios.get('/api/pages');
this.pages = res.data;
console.log(this.pages);
this.currentPage = this.pages[0];
console.log(this.currentPage);
return true;
} catch (error) {
console.log(error);
}
},
my "get" endpoint in pages.js:
router.get('/', async (req, res) => {
try {
let pages = await Page.find();
res.send({pages: pages}); //send result of search for pages as list of pages called "pages"
} catch (error) {
console.log(error);
res.sendStatus(500); //500 = server could not fulfill request
}
});
the route in server.js:
const pages = require('./routes/pages');
app.use('/api/pages', pages);
app.listen(3000, () => console.log('Server listening on port 3000!'));
module.exports = app;
and here's the console output, with the "pages" object from vue's data property and the "currentPage" that's supposed to be at pages[0] (printed to console in earlier example):
I can access the api at 'localhost:3000/api/pages' just fine, but how do I break into that array and access the first page object? I want to get an object from the list axios fetches from mongoose, then hold that object in a variable so I can access it's properties. The whole "pages > [[Target]] > pages > [ ]" is part of the problem I'm sure, but I don't know what to tell the code to open it.
Whoops! I realized my mistake. In pages.js I should have sent "res.send(pages);" After a whole couple days too XD
I'm trying to make graphql query calls using apollo on NuxtJS and I'm getting the following error.
WARN Missing field description in { 11:29:49
"__typename": "EduExp"
}
WARN Missing field componentName in { 11:29:49
"__typename": "EduExp"
}
{ 11:29:49
data: null,
loading: false,
networkStatus: 7,
stale: true
}
Here is my query
fragment IntroCardFields on IntroCard {
legend
profile {
title
url
}
introList
description {
json
}
componentName
}
query getPage($pageId: String!) {
page(id: $pageId) {
slug
name
componentsCollection {
items {
...IntroCardFields
}
}
}
}
I'm using it like this in vuex
async fetchPageData({ commit, state }) {
const apollo = this.app.apolloProvider.defaultClient;
const pageData = [];
const res = await apollo.query({
query: getPage,
variables: {
pageId: '2S3x7vBmaB2FhTUbNXWvwY',
},
});
console.log(res);
},
When I try this query without parameters on a api tool like postman or insomnia works well.
I don't get it why not working on Nuxt
Let me give an example: By accessing the following page we have access to all JSON code: https://jsonplaceholder.typicode.com/todos
But if I want I can retrieve just the first 6 elements of the JSON by accessing the following: https://jsonplaceholder.typicode.com/todos?_limit=6
I want to do this same thing with my Express code that I am accessing with http://localhost:3100
When I try http://localhost:3100?_limit=6 it brings the entire JSON file, I don't understand why. How can I fix this? I want the browser to be able to limit the amount that it gets from the API.
Here is my Express code:
const express = require("express");
const app = express();
const projects = [
{ project: "Challenges_jschallenger.com" },
{ project: "Using-Studio-Ghilis-API-With-JS-Only" },
{ project: "my-portfolio-next" },
{ project: "Youtube-Navbar-2021" },
{ project: "Mana-raWozonWebsite" },
{ project: "Movies-Website" },
{ project: "Add-Remove-Mark-and-Mark-off-With-ReactJS" },
{ project: "My-Portfolio" },
{ project: "Github_Explorer" },
{ project: "MestreALMO.github.io" },
{ project: "Tests-With-useState-useEffect-useRef" },
{ project: "Tic-Tac-Toe-React-in-JS" },
{ project: "ReactJS-with-TypeScript-Template" },
{ project: "Retractable-Accordion" },
];
app.get("/", function (req, res) {
res.send(projects);
});
app.listen(3100);
You need to extract the query from the express request. Also the correct way to respond with a json object would be to call the json method.
app.get("/", (req, res) => {
const { limit } = req.query
res.json(projects.slice(0, limit))
})
For it to work you would have to make the request to http://localhost:3100/?limit=6
Following the instruction at https://pro.ant.design/docs/router-and-nav#fetch-menu-from-server
I changed file BasicLayout.tsx as below. Menu is not showing up.
...
const testMenu = [{name:"login", path:"/user/login"}] as any;
const [menuData, setMenuData] = useState([]);
useEffect(() => {
if (dispatch) {
dispatch({
type: 'user/fetchCurrent',
});
}
setMenuData(testMenu)
}, []);
...
menuDataRender={()=>menuData}
...
I was doing same as you and failed as you. Document is still wrong.
And I found getting menu from server has a lot of bug with ant design pro v4. (Maybe I did not know)
So my final decision is to display all menu from /config/config.ts as designed initially.
And get only authorization information from server and set only authority to show only logged in user related menu.
So my solution (not correct answer) is:
I referenced this link. https://umijs.org/docs/runtime-config#patchroutes-routes-
Created file /src/app.tsx and inserted code as follow:
interface PathAndIdsModel {
path: string;
ids: string[];
}
const setAuthority = (routes: any, pathAndIds: PathAndIdsModel[]) => {
routes.forEach((route: any) => {
const found = pathAndIds.find((item) => item.path === route.path);
if (found) {
// eslint-disable-next-line no-param-reassign
route.authority = [...new Set([...(route.authority || []), ...found.ids])];
}
if (route.routes) {
setAuthority(route.routes, pathAndIds);
}
});
};
async function patchRoutes({ routes }) {
const response = await fetch(`https://localhost:44357/authorities`);
const pathAndIds = await response.json();
setAuthority(routes, pathAndIds);
}
export { patchRoutes };
Inserted following code to ASP.Net Core Controller:
[HttpGet("/authorities")]
public IEnumerable<object> Authorities()
{
return new[]
{
new {
Path = "/dashboard/analysis",
Ids = new [] { "user", "admin", },
},
new {
Path = "/dashboard/monitor",
Ids = new [] { "user", "admin", },
},
new {
Path = "/dashboard/workplace",
Ids = new [] { "admin", },
},
new {
Path = "/form/basic-form",
Ids = new [] { "admin", },
},
};
}
/dashboard/workplace and /form/basic-form page will be hidden if logged in as user, but shows if logged in as admin.
I tried to get full routes from server, but failed because of async call, UmiJS did not wait until fetching from server and setting new routes.
So when I fetched routes from server and changed routes, UmiJS already converted icon and component of old routes and my new routes never changed.