FeathersJS - add useUnifiedTopology to MongoDB - feathersjs

I'm using FeathersJS with MondoDB via feathers-mongo
I want to somehow pass useUnifiedToplogy:true to the connector's settings, however it doesn't seem to be exposed in the generated service (feathers generate service)
This is my logging.class.ts
import { Db } from 'mongodb';
import { Service, MongoDBServiceOptions } from 'feathers-mongodb';
import { Application } from '../../declarations';
import {Paginated, Params} from "#feathersjs/feathers";
export class Logging extends Service {
constructor(options: Partial<MongoDBServiceOptions>, app: Application) {
super(options);
const client: Promise<Db> = app.get('mongoClient');
client.then(db => {
this.Model = db.collection('users');
});
}
};

There's a mongodb.ts at root
import { MongoClient } from 'mongodb';
import { Application } from './declarations';
export default function (app: Application) {
const connection = app.get('mongodb');
const database = connection.substr(connection.lastIndexOf('/') + 1);
const mongoClient = MongoClient.connect(connection, { useNewUrlParser: true, useUnifiedTopology: true })
.then(client => client.db(database));
app.set('mongoClient', mongoClient);
}

Related

How to write a karma-Jasmine test for a dynamic configuration file JSON

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();
});
});

useFirestoreConnect returns empty object in react redux firebase

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

Shopify - How do I route between pages

I am new to Shopify App development and I try to implement routing inside my embedded Shopify App.
I have setup the ClientRouter and also integrated it inside the app.js (see below). When I set Navigation Links through the partners Account, the navigation menu appears and the links and the redirecting work as well.
As soon as I try to navigate the user to a page on a Button click, I get the error:
Expected a valid shop query parameter
I am trying to navigate the user by just giving the path for the page:
<Button url="/users">Users</Button>
My other files are listed below:
index.js
import { Page, Heading, Button } from "#shopify/polaris";
const Index = () => (
<Page>
<Heading>Index PAGE</Heading>
<Button url="/users"> Users </Button>
</Page>
);
export default Index;
app.js
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "react-apollo";
import App from "next/app";
import { AppProvider } from "#shopify/polaris";
import { Provider, useAppBridge } from "#shopify/app-bridge-react";
import { authenticatedFetch } from "#shopify/app-bridge-utils";
import { Redirect } from "#shopify/app-bridge/actions";
import "#shopify/polaris/dist/styles.css";
import translations from "#shopify/polaris/locales/en.json";
import ClientRouter from "../components/ClientRouter";
function userLoggedInFetch(app) {
const fetchFunction = authenticatedFetch(app);
return async (uri, options) => {
const response = await fetchFunction(uri, options);
if (
response.headers.get("X-Shopify-API-Request-Failure-Reauthorize") === "1"
) {
const authUrlHeader = response.headers.get(
"X-Shopify-API-Request-Failure-Reauthorize-Url"
);
const redirect = Redirect.create(app);
redirect.dispatch(Redirect.Action.APP, authUrlHeader || `/auth`);
return null;
}
return response;
};
}
function MyProvider(props) {
const app = useAppBridge();
const client = new ApolloClient({
fetch: userLoggedInFetch(app),
fetchOptions: {
credentials: "include",
},
});
const Component = props.Component;
return (
<ApolloProvider client={client}>
<Component {...props} />
</ApolloProvider>
);
}
class MyApp extends App {
render() {
const { Component, pageProps, host } = this.props;
return (
<AppProvider i18n={translations}>
<Provider
config={{
apiKey: API_KEY,
host: host,
forceRedirect: true,
}}
>
<ClientRouter />
<MyProvider Component={Component} {...pageProps} />
</Provider>
</AppProvider>
);
}
}
MyApp.getInitialProps = async ({ ctx }) => {
return {
host: ctx.query.host,
API_KEY: process.env.SHOPIFY_API_KEY,
};
};
export default MyApp;
ClientRouter.js
import { withRouter } from "next/router";
import { ClientRouter as AppBridgeClientRouter } from "#shopify/app-bridge-react";
function ClientRouter(props) {
const { router } = props;
return <AppBridgeClientRouter history={router} />;
}
export default withRouter(ClientRouter);
I am really looking forward to someone who can help me out! Thanks in advance!

DatabaseController in NodeJS MySQL with Typescript

I am developing a restAPI with nodejs, express and mysql. Now I have a app.js which is the starting point of the App.
Within app.js I initialize the UserController:
const router: express.Router = express.Router();
new UserController(router);
The UserController looks like this:
import { Request, Response, Router } from 'express';
import UserModel from '../model/user';
class UserController {
constructor(private router: Router) {
router.get('/users', async (req: Request, resp: Response) => {
try {
// const users = get Users with mysql
// resp.status(200).send(users);
} catch (error) {
resp.send({
msg: 'Not found',
status: 404
});
}
});
}
}
export default UserController;
Now I would like to have a DatabaseController which handels everything around the Database like providing a Connection, closing it and so on:
class DatabaseController {
constructor() {
}
}
export default DatabaseController;
How can I achieve that I open the connection in the DatabaseController and let the UserController simply access it? Is that even possible without initializing the DatabaseController and giving the UserController a parameter "dbConnection"?
Yes it's possible. I'm not entirely familiar with typescript so some psuedo code below. Untested.
Somewhere in another file, configure your database connection and the service:
import { MyConnection } from 'my-db-package';
class DatabaseService {
private connection: MyConnection
constructor(db: MyConnection) {
this.connection = db;
}
// Return the promise if any.
// Don't want to handle the error here.
// Let your controller handle the error
async openConnection() {
return this.connection.open()
}
async closeConnection() {
return this.connection.close()
}
async getAllUsers() {
return this.connection.query('SELECT * FROM USERS;')
}
}
export default DatabaseService;
import { Database } from 'my-db-driver'
import { DatabaseService } from 'my-db-service'
// Don't actually connect here
// Just create the object so it's ready for connection.
const connection = new Database({
// config
})
// Wire up the internal db connection
// Remember this is a singleton.
export default new DatabaseService(connection)
Next wire up your controller with the new database service:
import { Request, Response } from 'express';
import { DatabaseService } from './my-service'
class UserController {
private dbService: DatabaseService;
constructor(dbService: DatabaseService) {
this.dbService = dbService;
}
async connect() {
return this.dbService.openConnection()
}
async close() {
return this.dbService.closeConnection()
}
async getAllUsers(req: Request, res: Response) {
let users
try {
users = await this.dbService.getAllUsers();
} catch (error) {
// ...
}
res.json(users)
}
}
export default UserController;
Then hook up your routes:
import { express } from 'express'
import { UserController } from 'user-controller'
import { DatabaseService } from 'database-service'
const userController = new UserController(DatabaseService);
const router: express.Router = express.Router();
router.get('/users', userController.getAllUsers)
// ...
export default router
Finally, hook up your routes with the main Express app:
import { express } from 'express'
import { userRoutes } from 'user-routes'
const app = express()
app.use(userRoutes)
// ..
Again, the above code is untested and likely unusable. It is meant to give you an example of one approach. You may find a better way to do it, but that's the gist of it.

making API calls in angular redux app

I want to fetch json data from a server in a basic angular-redux todo app.Also please do explain how the data flow happens from the store.If u can kindly refer any blogs on the matter,it would be great.I could not make a lot of sense from ng2-redux or ngrx.Thank you in advance.
You should make API calls in Middleware. Read this book, its free, it will clear most of your doubts, it did it for me when I started learning.
You should make API calles (as knowen as side effects) with a middleware like Epic.
Let's considere an example of todo app that you need to get the todos from the server:
const BASE_URL = "https://some-server/api/";
#Injectable()
export class TodoEpics implements EpicMiddleware {
constructor(private httpService: HttpClient) {
}
#dispatch()
startLoading() {
return changeTodoStatus("loading");
}
getTodosEpic = (action$: ActionsObservable<GetTodosAction>, state$: StateObservable<AppState>): Observable<Action> => {
return action$.pipe(
ofType(todoConstants.GET_TODOS),
tap((action) => this.startLoading()),
mergeMap(action => this.httpService.get<GetTodosResponse>(`${BASE_URL}/todos`).pipe(
map((response) => getTodosSucceeded(response.items)),
catchError(error => of(getTodosFailed(error)))
))
);
}
getEpics(): Epic[] {
return [
this.getTodosEpic
];
}
}
and in the main store module:
import { NgModule } from '#angular/core';
import { NgReduxModule, NgRedux, DevToolsExtension } from '#angular-redux/store';
import { createLogger } from 'redux-logger';
import { AppState } from './models';
import { rootReducer } from './reducers';
import { TodoEpics } from "../todo-list/todo-list-state-management/epics";
import { combineEpics, createEpicMiddleware } from "redux-observable";
import { environment } from "../../environments/environment";
const epicMiddleware = createEpicMiddleware();
#NgModule({
imports: [NgReduxModule],
providers: [
TodoEpics
]
})
export class StoreModule {
constructor(private store: NgRedux<AppState>, private todoEpics: TodoEpics) {
const rootEpic = combineEpics(
...this.todoEpics.getEpics()
);
const middelwares = [epicMiddleware]
const devMiddelwares = [...middelwares, createLogger()];
const prodMiddelwares = [...middelwares];
store.configureStore(
rootReducer,
environment.production ? prodMiddelwares : devMiddelwares);
epicMiddleware.run(rootEpic)
}
}
a complete example can be found here: Todo app using angular-redux, redux-observable and epics