Strapi framework: can't get my page rendered - koa

I'm starting to play with Strapi framework and tried to use Handlebars and routes to show a page. I followed the docs and I created a controller with this:
find: function *() {
try {
yield this.render('user', {
firstname: 'John',
lastname: 'Doe'
});
} catch (error) {
this.body = error;
}
},
and a router file with this:
{
"routes": {
"GET /": {
"controller": "strap",
"action": "find"
}
}
}
It is working (no errors) but I get a 404 not found status and not my page that is in views/user.html as in the docs.
What am I missing?

Interesting... Your controller and route look good.
Make sure your config looks like this:
{
"views": {
"map": {
"html": "handlebars"
},
"default": "html"
}
}
You don't need to specify the file extension in your controller only if you have a default mapping key in your config. Otherwise you need to specify the extension like this:
find: function *() {
try {
yield this.render('user.html', {
firstname: 'John',
lastname: 'Doe'
});
} catch (error) {
this.body = error;
}
},
In your HTML file:
<html>
<body>
<p>Firstname: {{ firstname }}<br>Lastname: {{ lastname }}</p>
</body>
</html>

Oh it might be a conflict between your API routes and your public assets. Can you try to remove the ./public/index.html file?

Related

How to query data using graphQL based on slug value

I am working with GatsbyJS and GraphQL for the first time and trying to generate certain pages dynamically based on slug values.
Currently I am able to generate all of the relevant pages using the createPages API extension, but the pages are blank, no data is being retrieved.
I'm not quite sure how to retrieve the data from within the template. When I write the query I get errors like "GraphQLError: Syntax Error: Expected Name, found \"$\".", when adding $slug: string! for example.
Any help would be appreciated on this!
gatsby-node.js
exports.createPages = async function ({ actions, graphql }) {
const { data } = await graphql(`
query {
dataJson {
work {
slug
}
}
}
`)
data.dataJson.work.forEach(edge => {
const slug = edge.slug;
actions.createPage({
path: `work/${slug}`,
component: require.resolve(`./src/templates/work-article.tsx`),
context: { slug: slug },
})
})
}
template.js
export const query = graphql`
query($slug: String!) {
dataJson {
work(slug: $slug) {
slug
title
}
}
}
`;
gatsby-config.js
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'data', // Identifier. Will then be queried as `dataJson`
path: './src/assets/data', // Source folder containing the JSON files
},
},
Example of the data saved in data.json
{
"work": [
{
"slug": "my-slug",
"title": "My Title",
"img": "/static/img.jpg"
},
...
}

Strapi update username from custom controller

I am trying to create a custom controller to update the user profile.
I created the routing file and the corresponding controller.
Routing file: server/src/api/profile/routes/profile.js
module.exports = {
routes: [
{
method: 'GET',
path: '/profile',
handler: 'profile.getProfile',
},
{
method: 'PUT',
path: '/profile',
handler: 'profile.updateProfile',
},
]
}
Controller: src/api/profile/controllers/profile.js
async updateProfile(ctx) {
try {
const { id } = ctx.state?.user;
const user = strapi.query('admin::user').update({
where: { id },
data: {
username: "testUsername"
}
})
ctx.body = "User updated"
} catch(error) {
ctx.badRequest("Something went wrong", { error })
}
},
The above code returns "User updated", but the username does not update. I am executing the PUT call with a correct Bearer authorisation token and the user permissions for that user are set to enable "updateProfile".
Oddly enough, the same code, when changed to update a different API item, works perfectly fine:
async updateArticle(ctx) {
try {
const { id } = ctx.state?.user;
const article = strapi.query('api::article.article').update({
where: { author: id },
data: {
title: "New title"
}
})
ctx.body = article
} catch(error) {
ctx.badRequest("Something went wrong", { error })
}
},
I am also confused by different syntaxes appearing in the official Strapi documentation, for example some docs mention:
strapi.query('admin::user').update({ id }, data)
But in other places in the documentation its:
strapi.plugins['users-permissions'].services.user.update({ id });
And then elsewhere:
strapi.query('user', 'users-permissions').update(params, values);
Another question is: do I need to sanitise the input / output in any way? If yes, how? Importing sanitizeEntity from "Strapi-utils" doesn't work, but it's mentioned in several places on the internet.
Additionally, I cannot find a list of all ctx properties. Where can I read what is the difference between ctx.body and ctx.send?
The lack of good documentation is really hindering my development. Any help with this will be greatly appreciated.

How to get data by axios call in a mounted component?

I'm working on getting data from API by performing api call with axios. But my attempts to get data from api aren't succesful. How to make it work?
export default {
mounted() {
this.fetchData()
},
data() {
return {
users:[]
}
},
methods: {
fetchData(){
axios.get('api/person')
.then(response => (this.users= response.data))
.catch(error => console.log(error));
}
},
}
In ExampleComponent have these lines
<template>
...
<div>{{users.name}}</div>
<div>{{users.ip}}</div>
...
</template>
In api.php
Route::get('/person', function() {
$users = DB::table('user_info')->select('ip','name')->get();
return $users;
});
Running php artisan tinker I did
DB::table('user_info')->select('ip','name')->get();
I've got all my data from DB(users with names and IP's).
In the dev console, I see my data in response tab. But it is nothing in my page.
you need v-for:
<div v-for="user in users">
<div>{{user.name}}</div>
<div>{{user.ip}}</div>
</div>
so for every users you will show info.
There is a problem in vue : it should be {users.ip} and {users.name} in template.
that is how i get my data.
<script>
export default {
data() {
return {
properties: []
}
},
methods: {
loadproperty(){
axios.get('allhouses').then(response => this.properties = response.data);
},
},
mounted() {
this.loadproperty();
}
}
</script>

sequelize custom validator

I would like to create custom field validator with reference to existing field. What I did is to create a custom validator:
const User = sequelize.define('User', {
postalCode: {
type: DataTypes.STRING
},
country: DataTypes.STRING,
}, {
validate: {
wrongPostalCode() {
if (this.postalCode && this.country) {
if (!validator.isPostalCode(String(this.postalCode), this.country)) {
throw new Error('Wrong postal code')
}
}
}
}
});
User.associate = (models) => {
// TO DO
};
return User;
};
As you can see below in error message, we are getting this validator but in the row "path" there is validator name. I would like to change it for example to "postalCode" or somehow connect it with one field from the model. It is very important for me as this is related to Front-End and to parse it to correct form control.
enter image description here
Is there any way to do it?
Thank you in advanced :)
Have you tried to use a custom validator for the field instead? I haven't tried the following piece of code but should work and link the validator to the postalCode field.
const User = sequelize.define('User', {
postalCode: {
type: DataTypes.STRING,
validate: {
wrongPostalCode(value) {
if (this.country) {
if (!validator.isPostalCode(String(this.postalCode), this.country)) {
throw new Error('Wrong postal code');
}
}
}
}
},
country: DataTypes.STRING,
});

RestApi call through iron-ajax of polymer

I am developing a polymer app and I want to make a call to the RestApi.
this is the how the request body is
{
"languageId": Presently English is the only supported language. Always 1,
"productCode":"Medicus",
"timeZoneName":"Time zone name of device. For e.g. Asia/Calcutta",
"timeZoneOffset": Time zone offset from UTC in milliseconds. For e.g. IST = 19800000,
"user":{
"firstName":"First name of the user",
"lastName":"Last name of the user",
"middleName":"Middle name of the user",
"password":"Password provided by the user",
"userTypeId":2 = Doctor, 3 = User,
"fields":[
{
"Id":1,
"values":["Mobile number provided by the user”]
}
]
}
}
i am not getting the proper idea of how i should specify these parameters in the params='{}' of iron-ajax element.
Put something like this in your template (I am assuming POST to your rest API, since you said body in your question. If its GET replace body= with params=
<iron-ajax
id="fetchday"
url="/api/fetchday"
handle-as="json"
content-type="application/json"
method="POST"
body="[[params]]"
last-response="{{results}}"
on-response="_gotData"
on-error="_error"></iron-ajax>
And in your polymer element properties
Polymer({
is: 'my-element'
properties: {
params: {
type: Object
}
},
_someFunction: function() {
this.params = //ASSIGN YOUR JSON OBJECT TO PARAMS HERE
this.$.fetchday.generateRequest();
},
_gotData: function(e) {
//response data is in both this.results and e.detail.response
},
_error: function() {
}
});

Resources