Get DOM and control the data from router hook / Navigation Guards in vue3 - dom

I want to control the data after I enter the index page from quiz page, but I found that it's not possible to control the data by the method below, is it because the afterEach is global ?
Is there any other method that I can use to control the data inside index page when I came from the quiz page ?
I thought of using the vuex, if there's no other way, I'll try it.
this is my route:
const routes: RouteRecordRaw[] = [
{
path: '/',
component: () => import('layouts/MainLayout.vue'),
children: [
{
name: 'index',
path: '/',
component: () => import('pages/IndexPage.vue')
},
{
name: 'quiz',
path: '/quiz',
component: () => import('pages/QuizPage.vue')
},
],
},
this is my code in index:
setup() {
const router = useRouter()
const state = ref(1)
router.afterEach((to, from) => {
if (from.name === 'quiz') {
state.value = 2
}
})
return {
state,
}
}

Related

Redux toolkit query. useLazyQuery

Try to understand how to structure queries.
What I have now:
File for CRUD:
export const PromoService = apiClient.injectEndpoints({
endpoints: (build) => ({
fetchPromoById: build.query<
Promotion,
{ ppeType: PpeType; id: string }
>({
query: ({ ppeType, id }) => apiQuery(ppeType, 'fetchPromoById', id),
providesTags: (_result, _err) => [{ type: 'Promo' }],
}),
fetchPromoByCategory: build.mutation<
PromotionData,
{ ppeType: PpeType; type: string; bannerId: string }
>({
query: ({ ppeType, type, bannerId }) => ({
url: apiQuery(ppeType, 'fetchPromoByCategory'),
method: 'POST',
body: fetchPromoByCategoryBody(type, bannerId),
}),
invalidatesTags: ['Promo'],
}),
}),
});
export const { useLazyFetchPromoByIdQuery, useFetchPromoByCategoryMutation } =
PromoService;
File for slices:
const initialState: PromotionState = {
chosenPromotion: {} as Promotion,
promoList: [],
};
const promoSlice = createSlice({
name: 'promo',
initialState,
reducers: {
setChosenPromotion: (state, action: PayloadAction<Promotion>) => {
state.chosenPromotion = action.payload;
},
setPromoList: (state, action: PayloadAction<Promotion[]>) => {
state.promoList = action.payload;
},
},
});
Component:
const [fetchPromoByCategory, { isLoading, data: categoryData }] =
useFetchPromoByCategoryMutation({
fixedCacheKey: 'shared-update-promo',
});
const [trigger, result] = useLazyFetchPromoByIdQuery();
const chosenPromo = result.data;
useEffect(() => {
chosenPromo && dispatch(setChosenPromotion(chosenPromo));
}, [chosenPromo]);
There is no problem get data from useMutation in different components skipping the stage of store data via reducer.
Just use fixedCacheKey and it works fine.
Is it possible to use similar approach for getting data in different components with useLazyQuery?
I use additional dispatch to store data from useLazyQuery but I'm sure it's not appropriate approach.
It is perfectly valid to have multiple different query cache entries at once, so useLazyQuery will not initialize to one of them - it will get it's arguments once you call the trigger function.
It looks like you should use useQuery here, sometimes with the skip parameter when you don't want anything fetched from the start.

next js redirects not working in production page

const withPlugins = require("next-compose-plugins")
const withBundleAnalyzer = require("#next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
})
/**
* #type {import('next').NextConfig}
*/
const nextConfig = {
reactStrictMode: true,
async redirects() {
return [
{
source: "/",
destination: "/schedule/calendar",
permanent: false,
},
]
},
exportPathMap: async function () {
return {
"/": { page: "/schedule/calendar" },
}
},
}
const withTM = require("next-transpile-modules")([
"#fullcalendar/common",
"#fullcalendar/daygrid",
"#fullcalendar/interaction",
"#fullcalendar/react",
"#fullcalendar/timegrid",
])
module.exports = withPlugins([[withBundleAnalyzer({ nextConfig, target: "serverless" })], [withTM]], nextConfig)
This is my next.config.js file. In development page this working well, but in production page when i enter root page like 'example.com' show the /schedule/calendar page. Also i try to enter 'example.com/schedule/calendar' show the error This XML file does not appear to have any style information associated with it. I check aws s3 buckets i can't see schedule.html. How can i solve this problem

How to change the app route path if a page (walkthrough) has been view once

I have app walkthrough / intro built using ion-slides which is loaded as the default page in app.routing.module.ts .
{
path: '',
redirectTo: 'walkthrough',
pathMatch: 'full'
},{
path: 'walkthrough',
loadChildren: () => import('./walkthrough/walkthrough.module').then(m => m.WalkthroughPageModule)
}
I only want to show this the first time the app is launched, so my question is how do I configure the app-route in the app-routing module to set the opening page just once?
I read the documentation and could not find a reference.
For anyone in a similar situation you can add conditionals / user logic using angular route gaurds. In the Walkthrough.ts module I set the value to storage:
ngOnInit(): void {
// save key to mark the walkthrough as visited so the next time the user vistis the app, he would be redirected to log in
Storage.set({
key: 'visitedWalkthrough',
value: 'true'
});
}
In a walkthrough.gaurd.ts I check for same value and change the route based on same:
const { Storage } = Plugins;
#Injectable()
export class WalkthroughGuard implements CanActivate {
constructor(private router: Router) {}
async canActivate(): Promise<boolean> {
const { value } = await Storage.get({ key: 'visitedWalkthrough' });
if (value === 'true') {
// this is a returning user, don't show him the walkthrough
this.router.navigate(['auth']);
return false;
} else return true;
}
}
Good tutorial here :

Tabs Disappearing After Navigating Away (Side Menu + Tabs)

I have an app that uses a side menu and tabs based off the Ionic Conference App. The app works as expected at the start and the tabs and side menu are both shown but when you go to a non-tabs page and then back to a tabs page via the side menu the tabs disappear. Here’s my relevant code. Any one have any ideas why this may not be working as expected? :x
export class MyApp {
// Reference to the app's root nav
#ViewChild(Nav) nav: Nav;
rootPage: any;
pages: PageInterface[] = [
{ title: 'Applications', pageName: 'HomePage', index: 0, icon: 'home' },
{ title: 'New Entries ', pageName: 'JobEntryPage', index: 1, icon: 'map' },
{ title: 'Statistics', pageName: 'StatisticsPage', index: 2, icon: 'stats'},
];
socialPages: PageInterface[] = [
{ title: 'Company List', pageName: 'CompaniesPage', component:
'CompaniesPage', icon: 'log-out'}
];
accountPages: PageInterface[] = [
{ title: 'Profile', pageName: 'ProfilePage', component: 'ProfilePage', icon:
'person' },
{ title: 'Logout', pageName: 'LogoutPage', component: 'LogoutPage', icon:
'log-out'}
];
constructor(public platform: Platform, public statusBar: StatusBar, public
splashScreen: SplashScreen,
private afAuth: AngularFireAuth, public fb: FirebaseProvider,
public menu: MenuController) {
this.initializeApp();
this.afAuth.authState.subscribe(auth => {
if(!auth)
this.rootPage = 'LoginPage';
else
this.rootPage = 'TabsPage';
});
}
initializeApp() {
this.platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
openPage(page: PageInterface) {
let params = {};
// the nav component was found using #ViewChild(Nav)
// setRoot on the nav to remove previous pages and only have this page
// we wouldn't want the back button to show in this scenario
if (page.index) {
params = { tabIndex: page.index };
}
// If we are already on tabs just change the selected tab
// don't setRoot again, this maintains the history stack of the
// tabs even if changing them from the menu
if (this.nav.getActiveChildNavs().length && page.index != undefined) {
this.nav.getActiveChildNavs()[0].select(page.index);
// Set the root of the nav with params if it's a tab index
} else {
console.log(page.pageName)
this.nav.setRoot(page.pageName, params).catch((err: any) => {
console.log(`Didn't set nav root: ${err}`);
});
}
}

RouterConfiguration and Router undefined in aurelia

I am very new to Aurelia and just trying to apply navigation to my project.Though i import aurelia-router still it says RouterConfiguration and Router are undefined in constructor
import {Todo} from './ToDo/todo';
import {RouterConfiguration, Router} from 'aurelia-router';
export class App {
heading = "Todos";
todos: Todo[] = [];
todoDescription = '';
router :any;
list: any[];
constructor(RouterConfiguration: RouterConfiguration, Router: Router) {
this.todos = [];
this.configureRouter(RouterConfiguration, Router);
//console.log("klist", this.list);
}
//config.map() adds route(s) to the router. Although only route, name,
//moduleId, href and nav are shown above there are other properties that can be included in a route.
//The class name for each route is
configureRouter(config: RouterConfiguration, router: Router): void {
this.router = router;
config.title = 'Aurelia';
config.map([
{ route: '', name: 'home', moduleId: 'home/home', nav: true, title: 'Home' },
{ route: 'users', name: 'users', moduleId: './Friends/Friends', nav: true },
//{ route: 'users/:id/detail', name: 'userDetail', moduleId: 'users/detail' },
//{ route: 'files/*path', name: 'files', moduleId: 'files/index', href: '#files', nav: 0 }
]);
}
addTodo() {
if (this.todoDescription) {
this.todos.push(new Todo(this.todoDescription));
// this.todoDescription = '';
}
}
}
By convention, Aurelia looks in the initial class that loads (App) for the configureRouter() function and executes it. This means, you do not have to inject anything in the constructor.
It looks like you've simply added too much. I think fixing your sample seems to be as easy as removing some stuff, like so:
import { Todo } from './ToDo/todo';
import { RouterConfiguration, Router } from 'aurelia-router';
export class App {
heading = "Todos";
todos: Todo[] = [];
todoDescription = '';
list: any[];
constructor() {
// note: removed routing here entirely (you don't need it)
// also, you've already declared this.todos above, so no need to do it here again
}
configureRouter(config : RouterConfiguration, router : Router): void {
this.router = router;
config.title = 'Aurelia';
config.map([
{ route: '', name: 'home', moduleId: 'home/home', nav: true, title: 'Home' },
{ route: 'users', name: 'users', moduleId: './Friends/Friends', nav: true }
]);
}
addTodo() {
// removed this for brevity
}
}
This should resolve your 'undefined' errors on Router and RouteConfiguration. As an additional note, don't forget to add the <router-view> to your html template as well. Otherwise, you'll get no errors but the views won't show up either:
<template>
<div class="content">
<router-view></router-view>
</div>
</template>
Great documentation on this can be found at the Aurelia Docs - Routing.