Class export and import methods in Vue3 (Vue Cli) - vuejs3

I'm asking because I don't have an example.
To declare class, export, and import
What should I do?
test.js
export default class {
test() {
alert("ABC")
}
}
Main.vue
import exam from '../../test.js'
export default {
setup() {
exam.test()
}
}

import exam from '../../test.js'
import { ref } from 'vue'
export default {
setup() {
const class = ref(new exam())
}
}

Related

The dom is not reflective of the actual value wen using onPush strategy with ngrx store subscription

component file:
// Angular and 3rd party libs imports
import { ChangeDetectionStrategy, Component, OnInit } from '#angular/core';
import { Store } from '#ngrx/store';
import { UntilDestroy, untilDestroyed } from '#ngneat/until-destroy';
// Utils
import { ApiLoadInfo, ApiStateEnum } from 'src/app/shared/utils/states';
// Services
import { TestPortalService } from '../../../testportal.service';
import { SharedClient } from 'src/app/shared/services/shared.service';
// Redux
import {
CandidateInstructionsState,
Quiz,
Instruction,
PageEnum,
LandingPageData
} from '../redux/candidate-instructions.state';
import * as instructionActions from '../redux/candidate-instructions.action';
import * as instructionSelects from '../redux/candidate-instructions.selector';
import { ActivatedRoute } from '#angular/router';
#UntilDestroy()
#Component({
selector: 'candidate-instructions-landing',
templateUrl: './instructions-landing.component.html',
styleUrls: ['./instructions-landing.component.scss', '../common.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CandidateInstructionsLandingComponent implements OnInit {
// Exposing constants to html template
ApiStateEnum = ApiStateEnum;
PageEnum = PageEnum;
// Variables
initDataLoadState: ApiLoadInfo;
data: LandingPageData;
constructor(private _store: Store<CandidateInstructionsState>,
private _activatedRoute: ActivatedRoute,
private _testPortalService: TestPortalService,
) {
_store
.select(instructionSelects.selectInitDataLoadState)
.pipe(untilDestroyed(this))
.subscribe((initDataLoadState) => {
console.log('is same ref?:', this.initDataLoadState === initDataLoadState)
this.initDataLoadState = initDataLoadState;
console.log(initDataLoadState)
console.log('----------')
});
_store
.select(instructionSelects.selectLandingData)
.pipe(untilDestroyed(this))
.subscribe((data) => {
this.data = data;
});
}
ngOnInit() {
this.loadInstructions();
}
loadInstructions() {
this._store.dispatch(instructionActions.setInitData()); // sets state to 'loading'
this._testPortalService.getTestInstructions(
this._activatedRoute.snapshot.params.quizOrInviteId,
(error, response) => {
if (error) {
// sets state to 'error'
this._store.dispatch(instructionActions.setInitDataFail({ errmsg: error.toString() }));
} else {
// sets state to 'loaded'
this._store.dispatch(instructionActions.setInitDataSuccess({ instructions: response }));
console.log(response);
}
}
);
}
}
html:
{{ initDataLoadState.state }}
console output:
ui:
I thought when onPush is set, the template will re-render if the variable ref is changed. And since redux store is immutable that is always supposed to happen (confirmed by logging in the console). But still the actual component data is not in sync with the UI ie. component value = "loaded" but value in ui = "loading". Why is it so?
If you don't want to or can't use the pushPipe you could do something like this to subscribe to the store data:
import { Component, OnDestroy, OnInit } from '#angular/core';
import { Subscription } from 'rxjs';
import { Store } from '#ngrx/store';
import { getData } from 'path/to/store';
import { YourType } from 'path/to/type';
#Component({
selector: 'subscribing-component',
templateUrl: './subscribing.component.html'
})
export class SubscribingComponent implements OnInit, OnDestroy {
data: YourType;
dataSubscription: Subscription;
constructor(store: Store) {}
ngOnInit(): void {
this.dataSubscription = this.store.select(getData).subscribe((data) => {
this.data = data;
});
}
// don't forget to unsubscribe
ngOnDestroy(): void {
if (this.dataSubscription) {
this.dataSubscription.unsubscribe();
}
}
}

store is undefined in vue 3 class component unit testing

I am new to unit testing in vue 3 class component. I getting error says store is undefined. Here is my code in Home.vue file.
<script lang="ts">
import { Options, Vue } from "vue-class-component";
import HelloWorld from "#/components/HelloWorld.vue";
import { useStore } from "vuex";
import { key } from "#/store";
import { ProductType } from "#/types/commonTypeDefinitions";
#Options({
components: {
HelloWorld,
},
})
export default class Home extends Vue {
store = useStore(key);
get getAllProducts() {
return this.store.state.products ? this.store.state.products.groups : null;
}
mounted() {
if (!this.store.state.products) {
this.store.dispatch("getJsonData");
}
}
goToDetail(item: ProductType) {
localStorage.setItem("productDetail", JSON.stringify(item));
this.store.commit("setProductDetail", item);
const name = item.name.replaceAll(" ", "-");
console.log(name);
this.$router.push("/detail/" + name);
}
}
</script>
I am using jest for testing. Please help me with this.Thanks.

Change the RootPage

I am new to Ionic and I have a problem trying to push a rootpage on Ionic 3
On app.component.ts
import { Component } from '#angular/core';
import { LoginPage } from '../pages/login/login';
import { LoggedinPage } from '../pages/loggedin/loggedin';
import firebase from 'firebase';
#Component({
template: `<ion-nav [root]="rootPage"></ion-nav>`
})
export class MyApp {
rootPage: any;
var state = firebase.auth().onAuthStateChanged(function(user) {
if (user) {
this.rootPage = LoginPage;
//console.log(this.rootPage);
//from here i can see that the this.rootpage is defined.
} else {
this.rootPage = LoggedinPage;
}
console.log(this.rootPage);
//the rootpage is not defined outside of the funtion
});
}
What I want to do, id to redirect users that are already loggedin to the LoggedIn Page.
in app.component.ts
rootPage: any; is mistake, can you use rootPage: any = 'targetPage';
if you use menu rootPage: any = 'menuPage'; and chose rootPage in menuPage.ts ;
export class MenuPage {
rootPage = 'targetPage';
Need to change code following manner:
import {Component, ViewChild} from '#angular/core';
import {Nav} from 'ionic-angular';
import { LoginPage } from '../pages/login/login';
import { LoggedinPage } from '../pages/loggedin/loggedin';
import firebase from 'firebase';
#Component({
template: `<ion-nav [root]="rootPage"></ion-nav>`
})
export class MyApp {
rootPage: any;
#ViewChild(Nav) nav: Nav;
var state = firebase.auth().onAuthStateChanged(function(user) {
if (user) {
this.nav.setRoot(LoginPage);
//console.log(this.rootPage);
//from here i can see that the this.rootpage is defined.
} else {
this.nav.setRoot(LoggedinPage);
}
console.log(this.rootPage);
//the rootpage is not defined outside of the funtion
});
}
You should set userdata after login and clear on logout. and while setting rootPage you can check whether userdata does exist or not. And on initializeApp function of app.component.ts
initializeApp() {
this.platform.ready().then(() => {
this.rootPage = localStorage.getItem('userData') ? MyDashboardPage : LoginPage;
});
}

How to test effects in ngrx?

I just want to get my getUser effect below.
I'm using angular5, typescript and ngrx.
I'm open to alternative examples to what I have below.
This is my effect:
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/catch';
import { Effect, Actions } from '#ngrx/effects';
import { HttpErrorResponse } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { map, switchMap } from 'rxjs/operators';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import * as fromUser from '../actions/user-state.actions';
import { UserService } from '../services/user-state.service';
import { UserStateState } from '../models/user-state.interfaces';
#Injectable()
export class UserStateEffects {
#Effect({ dispatch: true })
getUser$: Observable<any> = this.actions$
.ofType(fromUser.GET_USER)
.pipe(
switchMap(() => this.userService.getUser()),
map((result: any) => new fromUser.UserSuccess(result)))
.catch((error: HttpErrorResponse) => of(new fromUser.UserFailure(error)));
constructor(
private actions$: Actions,
private userService: UserService
) {}
}
This is my spec for the effect test:
import 'rxjs/add/observable/throw';
import { Actions } from '#ngrx/effects';
import { cold, hot } from 'jasmine-marbles';
import { empty } from 'rxjs/observable/empty';
import { HttpClientTestingModule } from '#angular/common/http/testing';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { TestBed } from '#angular/core/testing';
import * as actions from '../actions/user-state.actions';
import { UserService } from '#tradingapplication/user-state/src/state/services/user-state.service';
import { UserStateEffects } from '#tradingapplication/user-state/src/state/effects/user-state.effects';
import { UserStateState } from '../models/user-state.interfaces';
import { UserStateConstants } from '../../user-state.constants';
export class TestActions extends Actions {
constructor(){
super(empty());
}
set stream(source: Observable<any>){
this.source = source
}
}
export function getActions() {
return new TestActions();
}
fdescribe('UserStateEffects', function () {
let actions$: TestActions;
let service: UserService;
let effects: UserStateEffects;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ HttpClientTestingModule ],
providers: [
UserService,
UserStateConstants,
UserStateEffects,
{ provide: Actions, useFactory: getActions },
],
});
actions$ = TestBed.get(Actions);
service = TestBed.get(UserService);
effects = TestBed.get(UserStateEffects);
spyOn(service, 'getUser').and.returnValue(of(null));
});
it('should return user from GetUser', () => {
const action = actions.GET_USER;
const completion = new actions.UserSuccess({});
actions$.stream = hot('-a', { a: action });
const expected = cold('-b', { b: completion });
expect(effects.getUser$).toBeObservable(expected);
});
});
You might want to check out the NGRX example app from the NGRX/Google team. It utilizes Jasmine-Marbles for testing streams, as used in NGRX Effects. This way you can test the streams for being closed or not after execution and how many elements passed through them before the expected value arrived. And all of that with just a few dashes (ticks).

Decorators in Meteor 1.4

I am trying to understand how decorators work with Meteor 1.4. From what I read, this feature is supported.
Now, I am unsure how to actually implement it. From this blog, to decorate a class, I would require this code
export const TestDecorator = (target) => {
let _componentWillMount = target.componentWillMount;
target.componentWillMount = function () {
console.log("*** COMPONENT WILL MOUNT");
_componentWillMount.call(this, ...arguments);
}
return target;
}
Then use it as
import React, { Component } from 'react';
import { TestDecorator } from 'path/to/decorator.js';
#TestDecorator
export default class FooWidget extends Component {
//...
}
The code compiles, but nothing gets output when the component is being rendered.
What am I missing? How do I implement a decorator in Meteor? Is this the proper solution? What is the alternative?
Edit
I have tried this, and it still does not work
export const TestDecorator = (target) => {
console.log("*** THIS IS NOT EVEN DISPLAYED! ***");
target.prototype.componentWillMount = function () {
// ...
};
}
You are assigning your componentWillMount function to the class FooWidget instead of its prototype. Change that to target.prototype.componentWillMount = …. Besides, storing the previous componentWillMount is unnecessary in this case because it is undefined anyway.
Here is a full working example:
main.html
<head>
<title>decorators</title>
</head>
<body>
<div id="root"></div>
</body>
decorator.js
export const TestDecorator = (target) => {
console.log('Decorating…');
target.prototype.componentWillMount = function() {
console.log('Component will mount');
};
};
main.jsx
import React, { Component } from 'react';
import { render } from 'react-dom';
import { TestDecorator } from '/imports/decorator.js';
import './main.html';
#TestDecorator
class FooWidget extends Component {
render() {
return <h1>FooWidget</h1>;
}
}
Meteor.startup(function() {
render(<FooWidget/>, document.getElementById('root'));
});
.babelrc
{
"plugins": ["transform-decorators-legacy"]
}

Resources