MethodNotAllowedHttpException using inertia - vue.js

I'm using Inertia and Laravel. I registered routes in web.php. When I send data to the server, I get error 405 which tells me MethodNotAllowedHttpException and the PUT methods is not allowed for this route but the data was updated successfully in database;
in question componet.vue
update(){
this.$inertia.put(`questions/${this.id}`, this.question, {
onSuccess: () => {
//do some stuffs
})
}
in QuestionsController.php
public function update(AskQuestionRequest $request, Question $question)
{
$question->update($request->only(['title', 'body']));
return redirect()->back()->with('successMsg', 'Your Question has been updated successfully');
}

This generally occurs when the Inertia middleware has not been installed in your app. If you recently upgraded the inertiajs/inertia-laravel package to 0.3.x, you need to follow the upgrade instructions here to install the middleware in your app.

Related

How to send static html file for dynamic routes in nest.js

I'm moving my existing project written on Express.js to Nest.js and one of the most pressing problem is to serve static html page for changing user's password. I've been looking for any answer for a couple of days, unsuccessfully. My implementation on Express.js works perfectly, here it is:
resetPass.use(express.static(__dirname + "/reset_pass_page"));
resetPass.get("/:id", async (req, res) => {
try {
// here I check ID which is JWT and if everything is OK I send the form:
res.status(200).sendFile(__dirname + "/reset_pass_page/index.html");
}
And now I'm trying to reach the same outcome using Nest.js. I got one single module for resetting password and sending links to user's email. Here is the controller:
#Controller('users/resetpass')
export class ResetPassController {
constructor(private readonly resetPassService: ResetPassService) { }
// here is others routes for getting reset link on user's email and etc...
// in this part I'm sending the form:
#Get("requestform/:id")
sendResetPasswordForm(#Param("id") resetToken: string) {
return this.resetPassService.sendResetPasswordForm(resetToken)
}
}
And what should I do in the service in my case?
async sendResetPasswordForm(resetToken: string) {
try {
// checking resetToken and if it's OK send form like:
res.sendFile(__dirname + "/reset_pass_page/index.html");
What method should i use in that case?
}
}
I've already tried to use ServeStaticModule in my reset pass modle, but I can't make it work properly with dynamic routes. I've tried this config:
ServeStaticModule.forRoot({
rootPath: join(__dirname, '../../../static/resetpass'),
renderPath: /(\/users\/resetpass\/requestform\/)([\w-]*\.[\w-]*\.[\w-]*)/g,
}),
I can make it work for routes without ID, like users/resetpass/, but I need to these page be available only for routes like users/resetpass/:id.
I'm looking forward for any help and advice. Thanks!
Similarly to what you did in Express.js:
res.status(200).sendFile(__dirname + "/reset_pass_page/index.html");
You can also use .sendFile in Nest.js
#Get("requestform/:id")
sendResetPasswordForm(#Req() req: Request, #Res() res: Response) {
const resetTokenPath = this.resetPassService.sendResetPasswordForm(pararms.id)
res.sendFile(join(__dirname, resetTokenPath, '/reset_pass_page/index.html'));
}
You have to add a couple of decorators and types from Express:
import { Controller, Get, Res, Req } from '#nestjs/common';
import { Response, Request } from 'express';

Shopify node backend- frontend communication

I am really new in shopify app development.
I have an allready a working app what i have created with next.JS (I have worked with node/express too)
I just would like to create a connection between my frontend and backend with a simple endpoint.
It means i send a get request and i receive something nonsense. The main goal would be that is the backend can communicate with the frontend.
I have created a git repo too.: https://github.com/akospaska/shopify-outofthebox
The app has been created with shopify-cli
In my pages folder there is an index.js file, where my frontend "lives". 
I have created (or i think ) 2 differend endpoints.
pages/api/test   endpoint: "/test"
server/server.js  endpoint: "/test2"
When i call the endpoints i get an error. 
I have read the documentation but it just makes me confused.
How should i authenticate between my backend and frontend exactly?
Thank you for your help Guys in advance.
The endpoints aren't pages, they are routes on your express app.
Here is a related question with answer:
Node backend communication between react frontend and node backend | Shopify related
Here is a checklist for you how to set up an endpoint (POST):
1.) Navigate to your index.js file in the /web directory
2.) Insert this code:
app.post("/api/test", async (req, res) => {
try {
res.status(201).send(response);
} catch (error) {
res.status(500).send(error.message);
}
});
}
app.post() sets up a route in your project.
3.) Navigate to your index.jsx file in /pages directory and insert this code (I set up a callback when a form submit button is clicked):
const handleSubmit = useCallback(
(body) => {
(async () => {
const parsedBody = body;
const response = await fetch("/api/test?shop=YOUR_SHOP_URL, {
method: "POST",
body: parsedBody
});
if (response.ok) {
console.log("Success");
}
})();
return { status: "success" };
},
[]
);
<Form onSubmit={handleSubmit}>
</Form>
it should call this API endpoint. So now you communicate with an API endpoint.
Maybe I could help you with my answer!

using redis in getServerSideProps results in error net.isIP is not a function

Correct me if I am wrong but getServerSideProps is used to pre-render data on each render? If I use the standard redis npm module in getServerSideProps I get the error net.isIP is not a function. From what I have researched this is due to the client trying to use the redis functions.
I am trying to create an application to where session data is saved in a redis key based on a cookie token. Based on the user Id a database is called and renders data to the component. I can get the cookie token in getServerSideProps but I I run client.get(token) I get the error net.isIP is not a function at runtime.
Am I not using getServerSideProps correctly or should I be using a different method / function? I am new to the whole Next.js world. I appreciate the help.
If I use the same functionality in an /api route everything works correctly.
import util from 'util';
import client from '../libs/redis' // using 'redis' module
// ... my component here
export async function getServerSideProps(context) {
const get = util.promisify(client.get).bind(client);
const name = await get('mytoken') // error `net.isIP is not a function`
return {
props: {
name
},
}
}
// redis.js
const redis = require("redis");
const client = redis.createClient();
client.on("error", function(error) {
console.error(error);
});
module.exports = client
I upgraded to next version 10.0.6 from 9.3 and I do not receive the error anymore.

vue server side rendering and data population

Im currently refactoring an app and converting all my base code into vue. One of my requirements is to do server side rendering.
I have been follow vue ssr example along with hacker news example to help me understand ssr.
I do have however a question for which I cant find any good answer, and before further development, I want to make sure we are doing the right thing.
I want to know if its a good practice to have some actions in a vue store calling an api for server side rendering.
All the examples I have found deal with a real external endpoint they connect and perform request. But that is not the setup we have.
We do have a "normal" express app with its own endpoints; so, for example, express router looks a bit like this:
// This is our post model, it lives on the same app, so its not a external API
app.get('/posts', (req, res) => Posts.getPosts());
// Resolve request for SSR rendering, pretty much the same as in [vue ssr example](https://ssr.vuejs.org/guide/routing.html#routing-with-vue-router)
app.get(
const context = { url: req.url }
createApp(context).then(app => {
renderer.renderToString(app, (err, html) => {
if (err) {
if (err.code === 404) {
res.status(404).end('Page not found')
} else {
res.status(500).end('Internal Server Error')
}
} else {
res.end(html)
}
})
})
);
This part works fine on both client and server. If you request something to /posts you get your response back.
To have a more modular code, we are using vuex stores; being one of the actions called fetchPosts and this action is the responsible of fetching the current posts in the view.
...
actions: {
fetchPosts({ commit }) {
return $axios.get('/posts').then((response) => {
commit('setPosts', {
posts: response.data
});
});
}
},
...
I believe for client side this is good, but when rendering on the server, this is probably not optimal.
Reason being axios performing an actual http request, which will also have to implement auth mechanism, and in general, really poor performant.
My question is: is this the recommended and standard way of doing this ?
What are other possibilities that works in server and client ?
Do people actually creates separated apps for api and rendering app ?
Thanks !
I know this is an old question, but for future visitors:
The recommended way is to leverage webpack module aliases to load a server side api for the server and a client side api for the browser. You have to share the same call signature which allows the api to be "swapped".
This of course greatly improves performance as the server side api can do direct db queries instead fetching data over http.
In essence your webpack.server.config.js should have:
resolve: {
alias: {
'create-api': './create-api-server.js'
}
}
In your webpack.client.config.js:
resolve: {
alias: {
'create-api': './create-api-client.js'
}
}
Importing create-api will now load the required api.
Have a look at https://github.com/vuejs/vue-hackernews-2.0 to see a full example.

XMLHttpRequest is not defined when testing react-native app with jest

i am trying to test a apiwrapper in a react-native based app using jest (integration testing).
When i run it in the iOs simulator everything runs fine however it wont run my jest tests correctly - i always get:
ReferenceError: XMLHttpRequest is not defined
when i try to run tests using my api wrapper, eg.:
it('Login successful with correct data', () => {
let api = Api.getInstance();
return api.login("test", "testpass")
.then(result => expect(result).toEqual('login_successful'));
});
the api class i am trying to test here does use the fetch api (not vanilla xhr). I assume its something related to jest trying to mock something but have not found a way to make it work yet.
Thanks in advance.
In my case, I'm not testing the search code but only importing it somewhere in my code path, so I decided to just mock it at the global level in a setup.js file (loaded using --require at test run). The following works for me:
// needed in react-instantsearch
class XMLHttpRequest {}
global.XMLHttpRequest = XMLHttpRequest;
I had a similar problem with lokka using XMLHttpRequest. I made a mock for lokka, which my api wrapper class depends on. You could try mocking your api wrapper.
This is what my lokka mock looks like for now. I'll add more to it when I start testing error handling.
export default class {
query() {
return new Promise(resolve => {
resolve(200);
});
}
}
You might be able to mock your api wrapper with something similar:
export default class Api {
getInstance() {
\\ However you implemented getInstance
}
login(user, password) {
return new Promise(resolve => {
resolve('login_successful');
});
}
}