Keep navbar title in sync with displayed page - vue.js

I'm working on a Vue project, where I have a navbar component. On mobile, this component shows a title for the page. I need to set this title on a page by page basis, but haven't been able to find a reliable way to do it.
I've seen examples suggesting adding meta: { title: 'My Page' } to each of the routes for the app, then checking the matched route and applying the title. This doesn't work for me as on some pages the title will rely on data fetched from displayed page (e.g. /posts/:id would want the title to be the title of the post, which isn't available to the router).
Another option I considered is emitting an event, which sets the title. This would work, but would have to be reflected up multiple levels, and would require every page to have a title otherwise the previous title would remain after navigation.
Similar to the above, it could be implemented via Vuex to avoid having to pass the event up the chain, but would have the same issue of the previous title remaining after navigation. I could of course clear the value on route change, but this could introduce a race condition as the API request is cached, so revisiting a cached page could result in no title.
Ideally I want a mix between using meta values, and values dependent on the result of the API call. What is the best way to achieve this?

Related

Vue Router: add working history item without invoking push

I have a vue page that displays a set of components in a certain order. Loading the page with the order will display those elements in order, for example:
https://mysite/dashboard/e3e1e2
will display components in order of 3,1,2 and
https://mysite/dashboard/e1e2e3
will display components in order of 1,2,3 etc.
If I change the order of the components in-page, for example by dragging them in a different order, I want to update my url so that it reflects the new order. There are two ways I can accomplish this:
this.$router.push({ path: '/dashboard/e3e2e1' }) // or this.$router.push({ name: 'dashboard', params: { elOrder: 'e3e2e1' } })
or
history.pushState({}, null, '/dashboard/e3e2e1'
For updating the URL, both work equally well. But here is the problem:
If I use this.$router.push my components are reloaded with all their data, when the only thing that has changed about them is their position on the page. However back and forward (history) works as expected.
If I use the history.pushState method, I can share that URL and it will load in the correct order for others, and the URL reflects the order on the page while viewing it, but forward navigation is broken (when I go back in history, the forward button will always be greyed out)
What I would like to accomplish is have a working history navigation without unnecessarily reloading all the components whose data has not changed in any way.

Routing to a page with sections in two slots

I have a question regarding routing.
We have a detail page that consists of two different sections.
However, these two components/sections are in different slots.
How does the routing work in such a case ?
How can we access the detail page ?
Is that even possible ?
Routing in Spartacus is not directly related to the structure of the CMS page. A url is connected to a page structure by using the following flow:
If it's a custom application route, spartacus will not touch it
if it's a product or category route, use configurable routing to match the product or category page from the cms
otherwise it's treated as a ContentPage, the CMS is queried for a matching page.label (or part of it).
if non of the above is found, the not-found content page is loaded.
The page structure which is loaded from the CMS is rendered on the page. The LayoutComponent is used to render the template, the PageComponent is used to render the page slots and the ComponentWrapperDirective is used to map the cms components to JS components.
If you have 2 different "sections", I assume you're talking about slots. In order to render the slots, you need to configure the Layout Configuration, see https://sap.github.io/cloud-commerce-spartacus-storefront-docs/page-layout/. Since the CMS doesn't provide any info on the order an location of slots, this additional configuration is required.
There's much more to it, but I hope this gives you a start at least.

How do you disable / fix this specific default behavior wherein after you refresh the whole webpage the specific router-link is still selected

Take a look at this pictures and description that I'm going to describe in the most understandable way possible.... These are my router-links
and on the side is the router-view / ProfileView.vue component that will display the details of that person, just don't mind the reds, it's just that those are very private keys to be displayed online
How do you disable /fix this specific default behavior wherein after you refresh the whole webpage the specific router-link is still selected and the router-view is invisible. Refreshing the page returns like this
Best way is to update the url with the unique identifier (UUID) once the item get selected. Now when you refresh the page just identify the item using the (UUID) in url and apply the specific item using active state. As per the router-view case you can easily handle it with the url defined case - make /profile:id expect a parameter, which will only provided when you click any of the router-link else redirect back to items page with the last selected UUID to highlight the last selected item

Force GET_ONE request when navigating to Show page

As I believe is common in many APIs, ours returns a subset of fields for a record when it is part of a List request, and more details when it is a single-record request to its Show endpoint.
It seems that react-admin attempts to avoid doing a second request when loading a Show page (possibly re-using the record data from List?), which results in missing data. Refreshing the page fixes this, but I'm wondering if there is a setting that will force a GET_ONE request on every Show page load.
There are no setting for that. However, this should be achievable with a custom saga which would listen to LOCATION_CHANGE action (from react-redux-router) and dispatch a refreshView action (from react-admin) when the new location pathname ends with /show.
Edit: however this is very strange. We only use the data we already got from the list for optimistic display but we still request with a GET_ONE when navigating to a show page from the list. Do you have a codesandbox showing your issue?

cache issue on shopify app

We are developing an app which will display a button on product details page to perform some actions. We are using product.metaifields for displaying the same based on a condition. So basically the button display toggles depending upon the metafield value.
The issue we are facing is, activate the feature from admin section and then the button will not show up on the user side unless we do a hard refresh on the browser. What happens here is Shopify caches the metafield value so the condition checking will not work.
Is there any way to remove the page caching while we perform some action on the app?
When you render a page in Shopify, it renders everything including the metafield resource values you may access while rendering. There is no special caching of a metafield value. If you render a metafield "AAA" on a client-facing page, change the metafield using an App or the Admin to be "BBB" there is no signal to the already rendered page to redraw anything.
If you want dynamic behaviour, like rendering a button with a value based on a metafield resource, you will have to either do a callback to an App, get the new contents, and update the DOM, or use a push strategy like WSS:// to keep a channel open to a backend that monitors these things.
So to sum up, your problem is not one of cached data, but instead the fact that you're rendering a non-dynamic value, and expecting your UX to be dynamic.