I am getting this error when I try to use rxjs in vue using vue-rx with rxjs.
[Vue warn]: Error in created hook: "TypeError: messageObservable.fromEvent(...).map(...).debounceTime is not a function"
I do not see any wrong imports from the documentation that I looked at and I am not getting any build errors when building the JS on my dev enviroment.
THese are the imports that I have
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
This is the fucntions calling these mehtods.
const messageObservable = Observable;
subscriptions(){
message$: messageObservable
},
created(){
message$.
fromEvent(document.querySelector('textarea'), 'input').
map(event => event.target.value).
debounceTime(500).
distinctUntilChanged().
subscribe({
next: function(value) {
console.log(value);
}
});
},
It seems that the tutorial you are following along is out to date. This imports are not longer working. (see changelog)
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
The latest and stable version is rxjs6. This is the correct way of using it:
import { fromEvent, map, debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'
import { Observable } from 'rxjs';
...
created() {
message$.
pipe(
map(event => event.target.value),
debounceTime(500),
distinctUntilChanged()
).subscribe(console.log);
}
I am guessing this is how you want to use fromEvent.
created() {
message$.
pipe(
switchMap(val => fromEvent(document.querySelector('textarea'), 'input'))
map(event => event.target.value),
debounceTime(500),
distinctUntilChanged()
).subscribe(console.log);
}
Related
I have a problem with useI18n that I'm unable to solve. Whatever I do, I am unable to get i18n translation to work and in my console perpetually see this message:
Uncaught SyntaxError: Must be called at the top of a setup function
The stack-track reveals that it happens when invoking the useI18n() function despite it being within a function called setup. The next level up the stack trace reveals that within the ```useI18n()`` function that an exception is being raised due to it not detecting an instance of my app.
function useI18n(options = {}) {
const instance = getCurrentInstance();
if (instance == null) {
throw createI18nError(I18nErrorCodes.MUST_BE_CALL_SETUP_TOP);
}
...
My code is as follows:
main.js
// frontend/src/main.ts
import i18n from './i18n';
import Vue, { createApp } from 'vue';
import axios from 'axios';
import VueAxios from 'vue-axios';
import App from './App.vue';
//Vue.use(VueI18n);
const app = createApp(App);
app.use(VueAxios, axios, i18n);
app.provide('axios', app.config.globalProperties.axios);
app.mount('#i-english-editor');
console.log(app);
i18n.ts
import { createI18n } from "vue-i18n";
const i18n = createI18n({
legacy: false,
locale: "ja",
fallbackLocale: 'en',
globalInjection: true,
messages: {
en: {
message: {
language: "English",
greeting: "Hello !"
}
},
ar: {
message: {
language: "العربية",
greeting: "السلام عليكم"
}
},
es: {
message: {
language: "Español",
greeting: "Hola !"
}
}
}
});
export default i18n;
App.vue
<div>
{{ t('message.greeting') }}
</div>
...
<script lang="ts">
import {defineComponent, ref, inject} from "vue";
import { useI18n } from "vue-i18n";
export default defineComponent({
setup() {
const { t } = useI18n();
...
return {
...
{t},
}
}
});
</script>
As you can see, my code looks like the various examples online showing me how to get translations working. I've looked at various solutions and none of them are working for me. This includes trying an alternative method of setting globalInjection to true and using {{ $t('message.greeting') }} in a tag which reveals the error:
ctx.$t is not a function
I am literally at a dead end and can't figure out a solution that seems to work for most people. My version of Vue is Vue 3 and the version of i18n I'm using is vue-i18n#9.2.0-beta.36.
If anyone knows why this is happening to me but no-one else, I'd appreciate it if you have a solution.
UPDATE - I managed to solve it.
To start with, I got rid of the need to use the useI18n function and realised that $t was failing due to multiple imports within the same app.use(...) function.
I changed it to:
app.use(VueAxios, axios);
app.use(i18n as any);
app.use was throwing up loads more errors into the console as i18n wasn't an accepted type. To get around the issue, I found out from a solution from another post that adding as any to it is a way around this problem. As a result {{ $t(...) }} is now producing the desired result.
I have a Vue 3 component that, when mounted in tests, cause warnings:
console.warn node_modules/#vue/runtime-core/dist/runtime-core.cjs.js:40
[Vue warn]: injection "Symbol(VueToastification)" not found.
at <ModifyJob ref="VTU_COMPONENT" >
at <VTUROOT>
I assume it's this one complaining https://github.com/Maronato/vue-toastification/blob/master/composition/index.js#L30.
I have nearly 100 of these warnings, so it's kind of hard to read test-run output. I've tried to mock provide for this dependency, but I can't seem to succeed:
let provide = {}
provide[VueToastification] = VueToastification
provide['VueToastification'] = VueToastification
provide[Symbol(VueToastification)] = VueToastification
provide[Symbol('VueToastification')] = VueToastification
provide['Symbol(VueToastification)'] = VueToastification
let options = {
global: {
provide: provide,
}
}
mount(ModifyJob, options)
Is this some Vue2/Vue3 incompatibility or do I just not understand the docs at https://vue-test-utils.vuejs.org/v2/api/#global-provide ? Can someone help me get rid of these warnings, ideally by allowing me to inject a mock so I can test that toasts are made?
That error actually indicates that the plugin isn't installed in the test Vue instance. You could make VueToastification available to the component under test through the global.plugins mounting option:
import { shallowMount } from '#vue/test-utils'
import MyComponent from '#/components/MyComponent.vue'
import VueToastificationPlugin from 'vue-toastification'
it('initializes', () => {
shallowMount(MyComponent, {
global: {
plugins: [VueToastificationPlugin]
}
})
})
Alternatively, if you want to verify that toast() (from VueToastification's useToast()) is called, you could mock vue-toastification:
import { shallowMount } from '#vue/test-utils'
import MyComponent from '#/components/MyComponent.vue'
jest.mock('vue-toastification')
it('should call toast', () => {
const toast = jest.fn()
require('vue-toastification').useToast.mockReturnValueOnce(toast)
shallowMount(MyComponent).vm.showToast()
expect(toast).toHaveBeenCalled()
})
I solved setting a global list of plugins according to https://next.vue-test-utils.vuejs.org/api/#config-global:
// In a jest.setup.js file
import { config } from "#vue/test-utils";
import VueToastificationPlugin from "vue-toastification";
config.global.plugins = [VueToastificationPlugin];
// In your jest.config.js
module.exports = {
...
setupFilesAfterEnv: ["./jest.setup.js"],
};
I'm currently using vue2-editor and importing quill modules and registering them as per documentation.But getting error window.Quill is undefined.
I've tried webpack plugin mix to include window.Quill and Quill but still error remains the same.
In my vue component
import { VueEditor } from "vue2-editor";
import { Quill } from "quill";
import { ImageDrop } from "quill-image-drop-module";
import { ImageResize } from "quill-image-resize-module";
Quill.register("modules/imageDrop", ImageDrop);
Quill.register("modules/imageResize", ImageResize);
And in my webpack mix
mix.extend('foo',new class{
webpackPlugins(){
return new webpack.ProvidePlugin({
"window.Quill": "quill/dist/quill.js",
Quill: "quill/dist/quill.js"
});
}
});
Uncaught TypeError: Cannot read property 'imports' of undefined
which is from window.Quill.imports
You need to get REALY working files from https://www.jsdelivr.com/package/npm/quill-image-resize-vue:
Just install npm i --save quill-image-resize-vue
and use another file:
import { VueEditor,Quill } from 'vue2-editor'
import ImageResize from 'quill-image-resize-vue';
import { ImageDrop } from 'quill-image-drop-module';
Quill.register("modules/imageDrop", ImageDrop);
Quill.register("modules/imageResize", ImageResize);
export default {
name: 'MainForm',
components: { VueEditor},
data() {
return {
content: '<h2>I am Example</h2>',
editorSettings: {
modules: {
imageDrop: true,
imageResize: {},
}
}
}
},
//........
}
For me got fixed after changing
import { ImageResize } from "quill-image-resize-module";
to
import ImageResize from "quill-image-resize-module";
i use method setTimeout in my users.component.ts but does not work and get
cannot find module 'timers' error
i import this code but does not work
import { setTimeout } from 'timers'
I have used SetInterval function, Also remove the import statement that is autogenerated.
Ex :
import { Component, OnInit } from '#angular/core';
//import { setInterval } from 'timers';
export class HelloWorldComponent implements OnInit {
message : string ;
constructor() {
setInterval(() => {
let currentDate = new Date();
this.message = currentDate.toDateString() + " " + currentDate.toLocaleTimeString();
}, 1000);
}
ngOnInit() {
}
}
Whenever you are using the setTimeout in our code,import { setTimeout } from 'timers'
then this import we will get by autogenerating code, once remove this import statement and run the code it should work, for me working fine.
`
Do not import setTimeout from 'timers'.
It will work without any importing
I see that in Angular 5 one should be using rxjs operators differently and importing from 'rxjs/operators' but I'm a little unclear on how it is supposed to work. I have something like:
import { Observable } from 'rxjs/Observable';
import { combineLatest, takeUntil } from 'rxjs/operators';
#Component({ ... })
export class FooComponent implements OnInit, OnDestroy {
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route_data = Observable.combineLatest(this.route.params, this.route.data,
(params, data) => ({params,data}));
this.route_data_sub = this.route_data.takeUntil(this.destroyed$).subscribe(
(params_and_data) => {
...
}
}
...
}
but I'm getting Observable.combineLatest is not a function errors. If I add the combineLatest operator the old way it works for combineLatest, but then takeUntil is now not found. How is this supposed to be done with Angular 5?
I have quite a bit of rxjs code all over the app and don't know how it is supposed to be rewritten or how to change the imports. Does everything have to be rewritten with .pipe() now?
You should import combileLatest use
import { combineLatest } from 'rxjs/observable/combineLatest';
For takeUntil
import { takeUntil } 'rxjs/operators';
I found that information:
combineLatest
takeUntil
#Mad Dandelion has the right answer but I figured it's worth showing what it looks like putting it together for anyone running across the same thing. You do have to pipe things like takeUntil. It's a bit of a pain to go through a large app and find all these spots but doesn't take that long. Doesn't look that bad either and has all the benefits in https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md under "why".
import { Observable } from 'rxjs/Observable';
import { combineLatest } from 'rxjs/observable/combineLatest';
import { takeUntil } from 'rxjs/operators';
#Component({ ... })
export class FooComponent implements OnInit, OnDestroy {
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route_data = combineLatest(this.route.params,
this.route.data,
(params, data) => ({params,data})
);
this.route_data_sub = this.route_data
.pipe(takeUntil(this.destroyed$)) //<-- pipe()
.subscribe((params_and_data) => {
...
})
}
...
}
Also in my case I had some stale dlls serving the older rxjs (https://webpack.js.org/plugins/dll-plugin/) so if you run into something that looks like your Observables don't have the pipe property, you might want to make sure the dlls are building properly if you use that.