How to update URL in redux simple router from action? - redux

According to the redux simple router docs, you can update the route from an action. I don't see how to do that in the documentation. Does anyone have an example of this?

You can import the history singleton passed to your root component into the action and operate on it directly, or, if you've installed the router middleware, you can use the action creators provided by react-router-redux.
From the docs:
What if I want to issue navigation events via Redux actions?
React Router provides singleton versions of history (browserHistory
and hashHistory) that you can import and use from anywhere in your
application. However, if you prefer Redux style actions, the library
also provides a set of action creators and a middleware to capture
them and redirect them to your history instance.
import { routerMiddleware, push } from 'react-router-redux'
// Apply the middleware to the store
const middleware = routerMiddleware(browserHistory)
const store = createStore(
reducers,
applyMiddleware(middleware)
)
// Dispatch from anywhere like normal.
store.dispatch(push('/foo'))
The following actions are supported:
push(location)
replace(location)
go(number)
goBack()
goForward()

Related

Pass date object from server component to client component in Next.js 13

I'm upgrading next.js project to app directory style project. I need to fetch data from api server that contains dates. Data then should be filtered and ordered by date field. Currently I'm using next-superjson library to serialize data that is sent from server to client from getStaticProps function. After upgrading call to api is done in server component that passes this data to client component. But that data cannot be serialized because of Date field. Is there any convenient was to overcome this serialization issue ? Or should I serialize manually data and pass it as string to my client component to render it ?
You can use next-superjson-plugin instead.
export default function ServerComponent() {
const date = new Date();
return <ClientComponent date={date} data-superjson />;
}
It provides data-superjson attribute for Server Component > Client Component Serialization.

Get current route in Next.js API route

I want to access my current route (eg /[user_id]/posts) for both regular pages and APIs, so that I can log it in errors, increase page hit counters, etc.
The only automated way I found to retrieve the current route involves useRouter, but that is only accessible in React components.
I want to avoid hardcoding a route in each of my handlers as that can get out of sync easily.
How can I automate retrieving the current route inside a handler?
It's simply not supported by the framework. There are 2 alternatives I found:
1/ Use another framework such as Nest.js. With Nest, you can access router information in an interceptor. E.g. with the Fastify adapter:
#Injectable()
export class InstrumentationInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
return next.handle().pipe(
tap(() => {
const ctx = context.switchToHttp();
console.log(ctx.getRequest().routerPath);
}),
);
}
}
2/ Create your own controller infrastructure and attach metadata to each controller, e.g.:
export class UserController extends BaseController {
getRoute(): string {
return "/user/:userid";
}
}
Note that you will need to manually keep routes in sync with your file structure. The above can be coded via Decorators too.
3?/ Theoretically you can configure a Custom Server in Nest and use a router that supports retrieving route paths, with a hook for you to retrieve the route (e.g. attach it to the request object during a middleware). If you find yourself doing this though, take a look at 1/.

Angular Web Component http calls are not routing through clients http interceptor

Set-up:
I have a web component (Angular 10) being used in an Angular 10 Application. The web component makes an Httpclient call to a web API to get some data to populate a menu dropdown. The web component was made using the standard methods to make a web component using Angular 10.
The web component is loaded through a script in the main client application. This is from the angular.json file for the parent application.
1."scripts":
[
"projects/web-component-test/src/assets/plugin.bundle.js"
]
and all works fine except we get a 401 error (unauthorized) since the end point requires the user to be logged in. By working fine, there are other controls that display as required just the the dropdown list, which gets it data from the API call does not get populated.
The flow:
User goes to website and then is prompted to log in (using keycloak Auth).
Application loads fine, except for the 401 error when the web component tries to load the menu items.
Http calls from the parent app work fine; the jwt token is added to the header for the call to the protected API. Calls from the child web component do not have the jwt token in the header, and thus fail with a 401 error.
httpinterceptor: we have an httpinterecptor on the main client application (the parent of the web control). Http calls that are made from the main app are routed through the interceptor where the token is attached to the header if needed.
Calls made from the child Web Component DO NOT hit the interceptor in the parent app?
Question:
How do I make call from the child web component route through the http interceptor in the parent so the token can be added.
Things I have tried:
I can get the web component to work fine if I do this:
When the parent loads I store the token in local storage
using an http interceptor on the web component, retrieve the token from local storage and use it.
** works, but I DO NOT want to store a secure token in local storage.
Pass the token in an attribute on the child component when the parent loads the child component
** again, I can get it to work, but not very secure.
A web component is an independent piece of code from your main codebase, so when you hit a request from the web component, your main app won't be able to catch those requests in the interceptor.
For me, one thing it worked was creating different Custom Events per every request:
doGetRequest
doPostRequest
doPutRequest
doDeleteRequest
Let me quickly guide you through one example of these events.
From the main app, I'm listening if any of these events are triggered:
this.popupEl.addEventListener('doPostRequest', (info: HTMLElementEventMap | any) => {
this.performHttpRequest(info.detail);
});
Notice that all the info sent from your web component, can be found in the property 'detail' your main app receives.
From the web component, I execute the following:
this.doPostRequest.emit({
url: 'the URL to hit',
endpointParams: {
user: 'my user',
password: '******',
}
});
Note: You can change the structure of the params to sent. It's totally up to you.
This will trigger the execution of the API in the main app, and as the request was executed from the main app, your interceptor will do its work and add whatever JWT you have there. Once the main app receives the response, you will need to set a new property in your web component to pass the response to it. Something like this:
this.popupEl.apiResponse = {
webComponentInfo: { ...infoReceivedFromYourWebComponent },
apiDetails: { ...ResponseFromYourBackend}
};
Finally, in your web component, add a new input that listen for the apiResponse attribute:
#Input()
set apiResponse(apiResponse: RequestParams) {
if (apiResponse.webComponentInfo.url === 'the URL to hit') {
// Do what you want in your web component, as you know exactly which URL just got executed.
}
}
This way, you let your main app continue doing its work with your interceptor and the web component won't need to handle the JWT or actually perform the requests.
One thing you may want to consider is not allowing the Delete request from your web component unless you and only you have full control over the web component. You wouldn't want anything that can perform a successful DELETE request to a very important API.
Hope this helps.

Shopware 6: Get PHP data in own custom admin module

I have build my own Plugin in Shopware 6. I allready have a custom module with custom route. Now I want to add data from my custom database table to my custom routes html.twig.
My Route: http://localhost:8888/admin#/ankauf/module/overview
My Database Table: product_reservation
I have build my own controller but I can't get this controller to listen to my route. Maybe because my route is build from the module? The path in my module is: ankauf.module.overview
Is a controller the right way? And if yes, how can it listen to my path and don't overwrite it with his own route?
Is there a better way to push PHP Code to my custom Backend path?
If you have created an own entity with definition etc (like here or here described) there is an easy to get your data to an admin module. Shopware will automatically register routes for CRUD operations on your entity. So the entity is automatically available via the admin API. On the admin side there are also helper services to read out your API. In your vue.js component you need to inject the
inject: [
'repositoryFactory'
],
With this factory you are able to create a repository which requests your custom entity API route.
{
...
created() {
this.repository = this.repositoryFactory.create('product_reservation');
}
}
The repository has several methods like search, get, create, delete, etc.
With these methods you are able to read out your data in the vue.js component of your plugin and bring it to your module
Read more about an own module here

intercept firebase-functions response (middleware)

For my Google Assistant/Dialogflow project, I am trying to intercept every response my firebase-functions endpoint is sending back to Dialogflow. I can easily intercept the request, but the response gets built within several functions (one function for every Intent), and I don't want to include an interceptor in every function.
Is it possible to have a middleware or is there a callback provided when a response is send out, sort of a global interceptor for every response?
I have found the following in the Docs: https://firebase.google.com/docs/functions/http-events#use_middleware_modules_with
However, I am unsure where this goes. Note that I am not using a custom express setup, but I am using the native implementation on firebase directly.
serialize() method is called on conversation right before the response is sent back, so what you can do is to extend the conversation object(based on the library you are using) and overwrite the serialize method to do whatever you need to do. don't forget to call the original serialize method and return the value in your new method.
Since you are using Dialog Flow with Firebase for your fulfilment, I am expecting you are also using actions-on-google package.
serialize() is a function which is called to generate the response. You can override this function and intercept the request and response. Try this code and thank me later. 😉
app.middleware((conv) => {
const serializeCopy = conv.serialize;
conv.serialize = () => {
const response = serializeCopy.call(conv);
console.log(conv.request, response);
return response;
};
});
Cloud Functions does not expose any sort of middleware or interceptors for HTTP requests or responses. You will have to build something yourself, probably with an Express app that you build yourself. You can host an Express app on Cloud Functions.
I wanted something similar to intercept all conversations back and forth for logging purposes. I ended up writing a function that I use to send a conversation. For eg:
const intercept = (conv, sentence) => {
//My Interceptor code
conv.ask(sentence)
}
Now anytime I want to send a response, I would use:
intercept(conv, "Speak this")

Resources