I am converting an existing app from vue 2 to 3.
I am having troubles with accessing globalProperties in components. In some instances using this.$propertyname returns undefined
In my main.js file:
import { createApp } from 'vue'
import App from './App.vue'
import {
appPageLoader
} from '#/store/reactives'
function mount(el){
let app = createApp(App)
app.config.globalProperties.$pgLoader = appPageLoader
// This console log returns proper value
console.log('^^^', appAnnouncer, app.config.globalProperties.$pgLoader)
app.mount(el)
}
mount('#app')
appPageLoader.js
This file contains a reactive object which we can import and assign to globalProperties $pgLoader
import { reactive } from "vue";
let pgLoader = {
pageLoadAnchor: null,
setFocusToTop () {
if (this.pageLoadAnchor instanceof HTMLElement) {
this.pageLoadAnchor.focus()
} else {
console.log('Cannot setFocusToTop() - pageLoadAnchor not found!')
}
}
}
let ReactivePageLoader = reactive(pgLoader)
export default ReactivePageLoader;
app.vue
When trying to access globalProperties using this.$property, I get undefined in component:
import { getCurrentInstance } from "vue";
mounted() {
this.$pgLoader.pageLoadAnchor = this.$refs.pageLoadAnchor; <- this.$pgLoader returns undefined
getCurrentInstance().appContext.config.globalProperties.$pgLoader = this.$refs.pageLoadAnchor; <- works but cumbersome
},
Related
My i18n boot file
import { boot } from 'quasar/wrappers';
import { LocalStorage } from 'quasar';
import messages from 'src/i18n';
import { createI18n } from 'vue-i18n';
const storedLang = LocalStorage.getItem('anty-locale');
const i18n = createI18n({
locale: storedLang && storedLang === 'en' ? 'en-US' : 'ru-RU',
messages,
});
export default boot(({ app }) => {
app.use(i18n);
});
export { i18n };
when I am trying to import in vuex js file like this
import { useI18n } from 'vue-i18n';
const { t } = useI18n({ useScope: 'global' });
I occur an error SyntaxError: Must be called at the top of a setup function
import i18n from 'boot/i18n';
i18n.t('common.user') //also doesn't work
Is there any correct way to import i18n in .js/.ts file?
I fixed like this and it worked.
import { i18n } from 'boot/i18n';
i18n.global.t('common.user'); // it works
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.
This Meteor React client code produces browser console error:
ReferenceError: CarsCol is not defined
Any idea why? Thanks
//cars.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import { composeWithTracker } from 'react-komposer';
import { ListItems } from '../containers/myList.jsx';
const composer = (props, onData) => {
const sub = Meteor.subscribe('carsCol');
if (sub.ready()) {
const cars = CarsCol.find().fetch(); //<------- error line
onData(null, {cars});
}
};
const Container = composeWithTracker(composer) (ListItems);
ReactDOM.render(<Container />, document.getElementById('react-root'));
//publications.js
const CarsCol = new Mongo.Collection('carsCol');
Meteor.publish('carsCol', function(){
return CarsCol.find();
});
You've defined the collection on the server only, you want to define the collection in both places.
What I would do is define your collection in a separate file and import that.
/api/collections/CarsCol
const CarsCol = new Mongo.Collection('carsCol');
Then in cars.jsx
import CarsCol from '../api/collections/CarsCol'
Given this subscription, and the React Component below, how do I pass the subscription data in as props 'searchTerms'? Most of the documentation I can find refers to using mixins, but as far as I understand this is an anti pattern in ES6. Thanks!
constructor() {
super();
this.state = {
subscription: {
searchResult: Meteor.subscribe("search", searchValue)
}
}
}
render() {
return (
<div>
<SearchWrapper
searchTerms={this.state.subscription.searchResult}
/>
</div>
)
}
There are a couple options when it comes to creating containers in Meteor. My personal favorite is react-komposer.
Here's what your container would look like using react-komposer. Note that a container is simply a component that just passes data, and in the case of Meteor, provides reactivity.
After npm install --save react-komposer, create a container using:
import { Meteor } from 'meteor/meteor';
import React from 'react';
import { composeWithTracker } from 'react-komposer';
import Component from '../components/Component.jsx';
import { Collection } from '../../api/collection/collection.js';
// Creates a container composer with necessary data for component
const composer = ( props, onData ) => {
const subscription = Meteor.subscribe('Collection.list');
if (subscription.ready()) {
const collection = Collection.find().fetch(); // must use fetch
onData(null, {collection});
}
};
// Creates the container component and links to Meteor Tracker
export default composeWithTracker(composer)(Component);
The standard way of doing this is to use the react-meteor-data package.
meteor add react-meteor-data
Then create a container as follows:
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
import SearchWrapper from '../pages/SearchWrapper.jsx';
import { SearchResults } from '../../api/searchResults.js';
export default SearchResultContainer = createContainer(({ params }) => {
const { searchValue } = params;
const searchHandle = Meteor.subscribe('search', searchValue);
const loading = !searchHandleHandle.ready();
const results = SearchResults.find().fetch();
const resultsExist = !loading && !!list;
return {
loading,
results,
resultsExist,
};
}, SearchWrapper);
The returned object from the container is available as props in the wrapped component - SearchWrapper.
I am building a Meteor app, and I am using the jStat library. I have some weird trouble with imports, using Meteor 1.3.
When I use the import { jStat } from jStat, my test are passing and jStat is correctly loaded. But it does not work in production, jStat object is undefined.
When I use the import 'jStat' syntax, that's the opposite... jStat is undefined in my test, but defined in my template.
Edit : I did install meteor-node-stubs, it did not change anything.
I also tried import * as jStat from jStat, but it only has the same effect than import jStat from jStat.
It seems to be an issue related to jStat itself, that has a weird loading behaviour (https://github.com/jstat/jstat#module-loaders).
Here are my files :
/imports/math/rates.js
import { jStat } from 'jStat';
/**
* Confidence interval calculation on proportions
* #return {[type]} [description]
*/
export const Rates = function(){
var self = this;
self.ualpha = function(alpha){
var mean = 0;
var std =1;
return jStat.normal.inv(1-alpha/2,0,1);
};
return self;
}();
/imports/math/rates.tests.js (the test file for rates.js)
import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { Events } from '/collections/events.js';
import { Stubs } from '/imports/testing/stubs.js';
import { TestHelpers } from '/imports/testing/helpers.js';
import { assert } from 'chai';
import { Rates } from '/imports/math/rates.js';
describe('Rates Helpers', () => {
beforeEach(()=>{
});
it("Should compute ualpha",()=>{
var eps = 10e-7;
assert.approximately(1.959964,Rates.ualpha(0.05),eps);
assert.approximately(1.644854, Rates.ualpha(0.1),eps);
assert.approximately(2.575829, Rates.ualpha(0.01),eps);
});
});
/client/rates/ui/pages/experiment.js (the template)
import { Template } from 'meteor/templating';
import { Rates } from '/imports/math/rates.js';
import 'meteor/manuel:viewmodel';
Template.rates_experiment.viewmodel({
alpha:0.01,
rate: 0.5,
precision: 0.01,
interval:'constant',
nIdeal : function(){
var self = this;
return Rates.nIdeal(self.rate, self.alpha, 'constant',self.precision);
}
});
Did anybody have the same issue with imports ?