I'm trying to import these files inside the perimeters folder
basePerimeter.js
byePerimeter.js
secretPerimeter.js
my import code:
import * as perimeters from '../perimeters'
basePerimeter.js
import { Perimeter } from 'vue-kindergarten';
export default class BasePerimeter extends Perimeter {
isAdmin() {
return this.child && this.child.role === 'admin';
}
}
byePerimeter.js
import basePerimeter from './basePerimeter';
export default new basePerimeter({
purpose: 'bye',
govern: {
'can route': () => true,
'can viewParagraph': function () {
return this.isAdmin();
},
},
});
secretPerimeter.js
import basePerimeter from './basePerimeter';
export default new basePerimeter({
purpose: 'secret',
govern: {
'can route': function () {
return this.isAdmin();
},
},
});
but if I import it individually, it works.
Like this:
import basePerimeter from '../perimeters/basePerimeter'
I need to import via * because of this code:
router.beforeEach((to, from, next) => {
const perimeter = perimeters[`${to.name}Perimeter`];
if (perimeter) {
const sandbox = createSandbox(child(store), {
perimeters: [
perimeter,
],
});
if (!sandbox.isAllowed('route')) {
return next('/');
}
}
return next();
});
Why is it throwing this error:
ERROR in ./src/router/index.js
Module not found: Error: Can't resolve '../perimeters' in 'E:\my\vue\instance\src\router'
# ./src/router/index.js 13:0-44
# ./src/main.js
# multi ./build/dev-client ./src/main.js
I Don't know what's happening here but adding an index.js file and importing the files I needed solved my problem.
index.js
import byePerimeter from './byePerimeter'
import secretPerimeter from './secretPerimeter'
export {
byePerimeter,
secretPerimeter
}
Related
I'd like to be able to listen to query param change events, preferably via a hook, but anything would be nice. I can't find anything that suggests it's even possible with react-router, so other suggestions without it are welcome too.
There's nothing in react-router-dom#5 that directly does this, so you'd need to implement this yourself. You can use the useLocation hook to access the location.search value to create a URLSearchParams object, then a useEffect hook to issue the side-effect based on any specific queryString parameter updating.
Example:
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
...
const { search } = useLocation();
const searchParams = new URLSearchParams(search);
const param = searchParams.get("param");
useEffect(() => {
// issue side-effect
}, [param]);
For RRDv5 there is this recipe to abstract the access of the query params:
import { useMemo } from 'react';
import { useLocation } from 'react-router-dom';
const useQuery = () => {
const { search } = useLocation();
return useMemo(() => new URLSearchParams(search), [search]);
};
...
import { useEffect } from 'react';
import { useQuery } from '../path/to/hooks';
...
const searchParams = useQuery();
const param = searchParams.get("param");
useEffect(() => {
// issue side-effect
}, [param]);
You can use useQuery and the useEffect hook to create another custom hook.
import { useEffect } from 'react';
import { useQuery } from '.';
const useQueryParam = (paramKey, cb) => {
const searchParams = useQuery();
const param = searchParams.get(paramKey);
useEffect(() => {
if (param) {
cb(param);
}
}, [param]);
};
...
import { useQueryParam } from '../path/to/hooks';
...
useQueryParam(
"myParameter",
(paramValue) => {
// do something with "myParameter" param value
},
);
did you tried below
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
function MyComponent() {
const location = useLocation();
useEffect(() => {
console.log('Location changed');
}, [location]);
...
}
I am very new to writing tests in Karma and Jasmine. In my case, I have a dynamic configuration file that loads before the app is initialized and that file is a JSON with a value.
configuration.json
{
"sampleConfigValue": "this is a sample value from config"
}
Configuration.ts
export interface Configuration {
sampleConfigValue: string;
}
ConfigurationService.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Configuration } from './configuration';
#Injectable({
providedIn: 'root'
})
export class ConfigurationService {
private configData: any | undefined;
private readonly configPath: string = '../assets/demo/data/config.json';
constructor(
private http: HttpClient
) { }
async loadConfiguration(): Promise<any> {
try {
const response = await this.http.get(`${this.configPath}`)
.toPromise().then(res => this.configData = res);
return this.configData;
} catch (err) {
return Promise.reject(err);
}
}
get config(): Configuration | undefined {
return this.configData;
}
}
Exporting the ConfigurationLoader in app.module.ts
export function configLoader(injector: Injector) : () => Promise<any>
{
return () => injector.get(ConfigurationService).loadConfiguration();
}
and Provider in app.module.ts
{provide: APP_INITIALIZER, useFactory: configLoader, deps: [Injector], multi: true},
configuration.service.spec.ts
import { TestBed } from '#angular/core/testing';
import { ConfigurationService } from './configuration.service';
describe('ConfigurationService', () => {
let service: ConfigurationService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ConfigurationService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
The configuration file is working but I am wondering how to write a test case for this dynamic configuration in my project?
Your time and help will really help me :)
Thanks :)
When unit testing, you're supposed to test a code unit and mock the rest.
So create a mock then test :
// Put this in the main describe
const returnValue = {};
let httpMock: { get: jasmine.Spy };
let service: ConfigurationService;
// Put this in the main beforeEach
httpMock = {
get: jasmine.createSpy().and.returnValue(of(returnValue)),
};
service = new ConfigurationService(<any>httpMock);
// Make a meaningful test
it('Should call the endpoint and retrieve the config', (done) => {
service.loadConfiguration().then(() => {
expect(httpMock.get)
.toHaveBeenCalledOnceWith(service['configPath']);
expect(service['configData']).toBe(returnValue);
done();
});
});
I am trying to create a todo app using react redux firebase. I have been able to connect the react redux firebase library to firebase as my create task actions produces changes in the firestore. But the redux store does not seem to be connected to firestore which is why I receive an empty object in console.log when i use fireStoreConnect in the useSelector hook.
store.js
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
// Redux
import { applyMiddleware, legacy_createStore as createStore } from 'redux';
import thunk from 'redux-thunk';
import { getFirebase } from 'react-redux-firebase';
import { getFirestore } from 'redux-firestore';
import { createFirestoreInstance } from 'redux-firestore';
// Reducers
import rootReducer from './reducers/rootReducer';
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: 'AIzaSyDOka0NyhrtvdX3hQihX0yVgHQ3m9f6Alg',
authDomain: 'todo-list-720.firebaseapp.com',
projectId: 'todo-list-720',
storageBucket: 'todo-list-720.appspot.com',
messagingSenderId: '770009943120',
appId: '1:770009943120:web:02fbc5adb060ee2cbc9555',
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// Initialize Firestore
firebase.firestore();
const rrfConfig = {
userProfile: 'users',
useFirestoreForProfile: true,
};
const store = createStore(
rootReducer,
applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore }))
);
const rrfProps = {
firebase,
config: rrfConfig,
dispatch: store.dispatch,
createFirestoreInstance,
};
export { store, rrfProps };
Home.js
import { useSelector } from 'react-redux';
import { useFirestoreConnect } from 'react-redux-firebase';
// Components
import Navigation from '../components/Navigation';
import TaskList from '../components/TaskList';
import AddTask from '../components/AddTask';
const Home = () => {
useFirestoreConnect(['tasks']);
const tasks = useSelector((state) => {
console.log(state.firestore);
return state.firestore.data.tasks;
});
return (
<>
<Navigation />
<AddTask />
<TaskList tasks={tasks} />
</>
);
};
export default Home;
rootReducer.js
import { firebaseReducer } from 'react-redux-firebase';
import { firestoreReducer } from 'redux-firestore';
const rootReducer = combineReducers({
firebase: firebaseReducer,
firestore: firestoreReducer,
/* auth: authReducer, */
tasks: tasksReducer,
});
image of firestore collection
CodeSandbox Link
I am developing angular REST application using ngrx/effects, I am using example application GIT. I am trying to replace hardcoded json data in effects, from http REST end. I am getting errors "Effect "GetTodoEffects.todo$" dispatched an invalid action" . Could you please help me in solving it. Every thing is same as git code, except effects code which is i am pasting below.
Effects code:
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/withLatestFrom'
import { of } from 'rxjs/observable/of';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { Action, Store } from '#ngrx/store';
import { Actions, Effect, toPayload } from '#ngrx/effects';
import * as Act from '../actions/app.actions';
import * as fromStore from '../reducers';
import { HttpClient } from '#angular/common/http';
#Injectable()
export class GetTodoEffects {
#Effect() todo$ = this.actions$.ofType(Act.GET_TODO)
.map(toPayload)
.withLatestFrom(this.store$)
.mergeMap(([ payload, store ]) => {
return this.http$
.get(`http://localhost:4000/data/`)
.map(data => {
return [
new Act.GetTodoSuccess({ data: data })
]
})
.catch((error) => {
return [
new Act.GetTodoFailed({ error: error })
]
})
});
constructor(
private actions$: Actions,
private http$: HttpClient,
private store$: Store<fromStore.State>
) {}
}
I am using json-server as REST end point. json-server --port 4000 --watch expt-results-sample.json
expt-results-sample.json
[
{
text: "Todo 1"
},
{
text: "Todo 2"
},
{
text: "Todo 3"
}
]
})
]
First thing I suspect is the array. Try changing it to an observable.
return this.http$
.get(`http://localhost:4000/data/`)
.map(data => {
// You don't need an array because it's only 1 item
// If you want array use `Observable.from([ /* actions here */ ])`
// but then you'll need to change `map` above to
// `mergeMap` or `switchMap`
// (no big difference for this use case,
// `switchMap` is more conventional in Ngrx effects)
return new Act.GetTodoSuccess({ data: data });
})
.catch((error) => {
// You probably haven't called this yet,
// but `catch` must return `Obsrvable`
// Again, if you want an array use `Observable.from([ /* array */ ])`
return Observable.of(
new Act.GetTodoFailed({ error: error })
);
})
I've been following this tutorial (https://www.turbo360.co/tutorial/redux-walkthrough) and I keep trying to run webpack but the build keeps failing. Any one know why it keeps crashing?
import { createStore, appMiddleware, combineReducers } from 'redux'
import thunk from 'redux-thunk'
import { todoReducer } from './reducers'
let store = null
export default {
createStore: () => {
const reducers = combineReducers({
todo: todoReducer
})
store = createStore(
reducers
appMiddleware(thunk)
)
return store
},
currentStore: () => {
return store
}
}
Does anyone know the solution?
You need to import applyMiddleware, not appMiddleware. It's a typo.
applyMiddleware