Nuxt 2.12.2: Filling the store with the new fetch method - vue.js

It is not clear in the current documentation, since the big change on the fetch method. As I understand that in the doc it says:
fetch(context) has been deprecated, instead you can use an anonymous middleware in your page: middleware(context)
So context is no longer available? What is passed into the new fetch method then?
And how do you access the store in the context? For example, prior to 2.12.2, we can use the fetch method as follows:
// pages/index.vue
async fetch ({ store }) {
await store.dispatch('....')
},
So, I assume that the code above will not be working soon in Nuxt 3 in the future. Then how do you fill the store data when you are on a page?
Currently, it seems that you still can access the context as the first argument in the new fetch method. What about in the future?

what is passed into the new fetch method then?
The fetch hook no longer has any arguments.
how do you access the store in the context?
To access the context within the fetch hook, use this.$nuxt.context; and you can access the store like this:
const { store } = this.$nuxt.context
store.dispatch(...)
// or
this.$nuxt.context.store.dispatch(...)

Related

Svelte/Sapper fetch/this.fetch is not defined in Server side API

Here is my question about using Svelte/Sapper
I have a file in /src/routes/login.js
According to Sapper doc, it will create an API endpoint in http://<my_domain>/login, which it does
Now in login.js, I would like to call another API server, assume that it is http://another_server/auth
No matter how I use the fetch function: fetch("http://another_server/auth"), this.fetch("http://another_server/auth"), Svelte responses: (this.)fetch is not defined.
The documentation said that it should be run within preload(), so I wrap the fetch under export async function preload(){}, it did not work
So my question is: other than using axios, can I keep on using fetch in server side API request?
Just tested in the template [slug].json.js file, when I add the (this.)fetch function, it did not compile, same error: (this.)fetch is not defined
Thank you very much.
Install the node-fetch npm package and use that in your server routes instead of the default fetch.
(in /src/routes/login.js):
import fetch from 'node-fetch'
...
// inside your route handler
const response = await fetch('http://another_server/auth') // no error
If you are unsure if the code will be executed on the client-side or the server-side (i.e. you're looking for a universal/isomorphic approach) you can use a conditional require:
// inside your route handler
const fetch = process.browser ? window.fetch : require('node-fetch').default
const response = await fetch('http://another_server/auth') // no error
But this is probably overkill in your use case since server routes are by definition executed on the server side.

Nodejs how to pass parameters into an exported route from another route?

Suppose I module export "/route1" in route1.js, how would I pass parameters into this route from "/route2" defined in route2.js?
route1.js
module.exports = (app) => {
app.post('/route1', (req,res)=>{
console.log(req.body);
});
}
route2.js
const express = require('express');
const app = express();
//import route1 from route1.js
const r1 = require('./route1')(app);
app.post('/route2', (req, res) => {
//how to pass parameters?
app.use(???, r1) ?
})
In short, route 1 output depends on the input from route 2.
You don't pass parameters from one route to another. Each route is a separate client request. http, by itself, is stateless where each request stands on its own.
If you describe what the actual real-world problem you're trying to solve is, we can help you with some of the various tools there are to use for managing state from one request to the next in http servers. But, we really need to know what the REAL world problem is to know what best to suggest.
The general tools available are:
Set a cookie as part the first response with some data in the cookie. On the next request sent from that client, the prior cookie will be sent with it so the server can see what that data is.
Create a server-side session object (using express-session, probably) and set some data in the session object. In the 2nd request, you can then access the session object to get that previously set data.
Return the data to the client in the first request and have the client send that data back in the 2nd request either in query string or form fields or custom headers. This would be the truly stateless way of doing things on the server. Any required state is kept in the client.
Which option results in the best design depends entirely upon what problem you're actually trying to solve.
FYI, you NEVER embed one route in another like you showed in your question:
app.post('/route2', (req, res) => {
//how to pass parameters?
app.use(???, r1) ?
})
What that would do is to install a new permanent copy of app.use() that's in force for all incoming requests every time your app.post() route was hit. They would accumlate forever.

View model with the authorization example

I want to restrict access to view models according to the authorization or JWT. I found examples for the read models, but how to implement it for the view models in the right way?
In resolve framework every view-model can have own serializer and deserializer. These functions are used for view-models which have non-trivial state object, which cannot be automatically serialized by JSON.stringify and be restored within JSON.parse - for example, it's useful for Immutable.JS or seamless-immutable.
In fact serializer has two arguments - first is state object for serialization, and second argument is JWT token from invoker. Since view-model is always had been invoked from current client, either HTTP request or API handler, JWT token is always present and can be used for access restriction
const serializeState = (state, jwtToken) => {
if(jwtToken != null && !isGoodToken(jwtToken)) { // JWT token is present and custom validation failed
throw new Error('Access denied')
}
return JSON.stringify(state) // Or custom serialize procedure
}
export default serializeState
Important notice: do not restrict serialized state access in case of jwtToken absence, since it used for internal purposes in snapshot adapters. Always allow return serialized state if second argument is undefined. Else if jwtToken present and invalid, error can be thrown to restrict access.

Get all available values in Office.context.mailbox.item for Outlook

Is there an api to access get all available values async in Office.js, specifically Office.context.mailbox.item in Outlook?
I do not see anything in the docs.
I need to capture 10 or so fields, and to date have only implemented with callbacks, e.g.
var ITEM = Office.context.mailbox.item;
var wrapper = //fn to parse results and call next field getAsync as cb
ITEM.end.getAsync(wrapper);
The documentation reference you have provided stated the Office.context.mailbox.item is the namespace. The namespace don't have the method which would enumerate all other methods in the namespace and return some consolidated result, instead you would use specific method, get the result and move to the next method you are interested in. This is all Office.js API offered for the item.
If you need to get several item properties at once, you may look at EWS request support of Office.js API by calling to Office.context.mailbox.makeEwsRequestAsync. Inside your XML request you may specify fields you are interested in and retrieve them with one request/response. Refer to Call web services from an Outlook add-in article for more information.
Yet another option to get several item properties at once is to Use the Outlook REST APIs from an Outlook add-in
I solved this with jQuery.when
const dStart = $.Deferred()
const dEnd = $.Deferred()
Office.context.mailbox.item.start.getAsync((res) => {
// check for errors and fetch result
dStart.resolve()
})
Office.context.mailbox.item.end.getAsync((res) => {
// check for errors and fetch result
dEnd.resolve()
})
$.when(dStart, dEnd).done(function() {
// will fire when d1 and d2 are both resolved OR rejected
}
If you don't want jQuery you can use promises and Promise.all

ExtJs 4 Store's AJAX proxy is not called on Store add — what is missing?

I have a Grid, a Store and Model for its data and AJAX proxy for the Store that is pointing to my self-written PHP back-end. The PHP backend writes to log each time it is called.
The system works OK for Read, Update and Delete calls. However now I need to add new field to Store, which I do in such a way:
(here, some new data were generated...)
var newEntry=Ext.ModelManager.create({
id:id,
title: title,
url: '/php/'+fname,
minithumb: '/php/'+small,
thumb:'/php/'+thumb
}, 'MyApp.model.fileListModel');
var store=Ext.getCmp('currGallery').getStore();
store.add(newEntry);
store.sync();
I have the new line appearing in the Grid.
But with or withour sync() call, I have no calls going to my PHP back end. It however reads one more time. Store has parameter autoSync :true and does great updating data automatically when I edit existing line in the Grid.
What am I missing?
Try not to set id when creating new record.
In fact I was missing a
newEntry.phantom = true;
flag. After I set it before adding to store, Store and its Proxy started to send data to server.
Maybe ID solution also works, dunno.