Requests¶
If you prefer to navigate using Javascript, or need more functionality than what UJS
offers, Superglue comes with two functions built around fetch
, visit
and
remote
. These are wrapped with your own implementation in
application_visit.js and can be accessed via the NavigationContext.
Tip
Superglue does not come with a <Link>
component. Instead we encourage you to
build one that is unique to your projects needs using the functions provided by
the NavigationContext.
import { NavigationContext } from '@thoughtbot/superglue';
const { remote, visit } = useContext(NavigationContext)
visit¶
visit
is designed to mimic browser navigation for clicks and
form submissions without the impact of a full page reload. There can be only one
visit at a time and when successful visit
will swap out the current page
component for the next one.
At glance it looks like this:
sequenceDiagram
autonumber
Browser ->> Superglue: Click request to `/posts/new` intercepted
activate Superglue
Superglue -->> Server: Re-request with format JSON `/posts/new.json`
activate Server
Server -->> Superglue: `/posts/new.json` response
Superglue -->> Superglue: Save response and swap page components
deactivate Server
Superglue -->> Browser: Update browser history, scroll position
deactivate Superglue
Hint
Its possible to modify the visit payload before it saves to the store. See the beforeSave callback.
- See complete reference
for
visit
remote¶
Use remote
when you want to asynchronously update parts of a page or save a
page to the store without swapping the page component or change the browser
history. Unlike visit, you can fire off as many async remote
requests
as you want.
Hint
Its possible to modify the remote payload before it saves to the store. See the beforeSave callback.
At glance it looks like this:
sequenceDiagram
alt target default current page
autonumber
Browser ->> Superglue: Click request to `/posts/new` intercepted
activate Superglue
Superglue -->> Server: Re-request with format JSON `/posts/new.json`
activate Server
Server -->> Superglue: `/posts/new.json` response
Superglue -->> Superglue: Save response
Superglue -->> Browser: User on current page sees update
deactivate Server
deactivate Superglue
end
By default, remote
derives a pagekey
from the response to save the page.
You can override this behavior and expliclity pass a pageKey
option to target
a different page in the store. If the user is not viewing the target page, they
will not see an update.
Warning
The componentIdentifier from the page response MUST match the target page, otherwise
remote will throw a MismatchedComponentError
error. You can override this by using the
force: true
option. See the docs
for details.
sequenceDiagram
alt target another page in the store
autonumber
Browser ->> Superglue: Click request to `/posts/new` intercepted
activate Superglue
Superglue -->> Server: Re-request with format JSON `/posts/new.json`
activate Server
Server -->> Superglue: `/posts/new.json` response
Superglue -->> Superglue: Save response or update target page
Note right of Browser: User does not see an update to the current page
deactivate Server
deactivate Superglue
end
- See complete reference
for
remote
- See note
for differences between
remote
anddata-sg-remote
Customizations
You can modify the behavior of visit
and remote
functions globally from
application_visit.js
. If you need a global customization, e.g, progress
bars, you can add them there.
The beforeSave
callback¶
Note
beforeSave
is an advanced Supeglue feature. Before proceeding please familiarize
yourself with:
- Knowing how Fragments and FragmentRefs work, the first
parameter passed to
beforeSave
is a proxy that lazily normalizes fragments. - How to get the unproxied state.
- Knowing the shape of savePage or graft responses.
- Knowing how denormaliztion works
Both visit
and remote
can be passed a beforeSave
callback. This is your
opportunity to modify the incoming savePage or graft
payload before it persists. Its ideal for features like
infinite-scroll where you need to
concatenate a list of results into an existing list:
const beforeSave = (prevPageProxy, receivedResponse) => {
receivedResponse.data.messages = [
prevPageProxy.data.messages,
... receivedResponse.data.messages
]
return receivedResponse
}
remote("/posts", {beforeSave})
Warning
If you are concatenating arrays in a beforeSave
callback and using nesting
Fragments like so:
index.json.props
_post_list.json.props
_post.json.props
be sure to use the key to help Superglue identify fragments in the concatenated array.
_post_list.json.props
- json.array!(partial: ["post", fragment: ->(post){"post-#{post.id}" }]) do
+ json.array!(partial: ["post", fragment: ->(post){"post-#{post.id}" }, key: :id]) do
end
This will ensure that Superglue denormalizes the fragments properly.