vuejs2 - two npm packages have same prop - javascript

I am stuck at one point here. I am building a multilingual website for which I have used the package vue-multilanguage https://github.com/leonardovilarinho/vue-multilanguage
I have registered the package in my main.js as below -
import MultiLanguage from 'vue-multilanguage'
import resources from './resources/resources'
Vue.use(MultiLanguage, resources)
to set a language dynamically, the code I have used is
this.language = fr //example.
It works like a charm, no issues..
Now, the problem arises when I use a datetime picker from https://www.npmjs.com/package/vuejs-datepicker.
I register it in my component as
import Datepicker from 'vuejs-datepicker';
export default {
name: 'UserCustEmpRelationship',
components: {
Datepicker
},
}
Now this datepicker also has a prop called language. Coincidentally my multilanguage package also has a data property called language(I set it to this.language).. My guess is that the datepicker is confusing the two language and giving the error as -
The data property "language" is already declared as a prop. Use prop default value instead.
found in
--->
Any help will be highly appreciated

Related

Why is dynamic importing of dayjs not working in typescript?

I am working on a web screen inside a .NET app and I am trying to send date time preference from the system to the web screen using CefSharp settings and setting
AcceptLanguageList = CultureInfo.CurrentUICulture.Name
In my typescript code I want to use dayjs and import dynamically 'dayjs/locale/${language}' where language comes from AcceptLanguageList above.
import React, { useState } from 'react';
import dayjs, { Dayjs } from 'dayjs';
import localeData from 'dayjs/plugin/localeData';
dayjs.extend(localeData);
var lang = navigator.languages != null ? navigator.languages[0] : navigator.language;
lang = lang.toLowerCase();
import(`dayjs/locale/${lang}`).then(
() => {
dayjs.locale(lang);
setAdapterLocale(lang);
});
The thing is, when I run this code in browser and try to import 'dayjs/locale/fr-ca', for example, it works fine, but when 'fr-ca' comes from CefSharp, then the import fails with
Uncaught (in promise) TypeError: Failed to resolve module specifier
'dayjs/locale/fr-ca'
Any help is much appreciated.
If you want to use a dynamic path for the dynamic import then you'll first have to list all of the possible paths that you will potentially want to have, otherwise your bundler wont know which files to include.
You can add import('dayjs/locale/fr-ca') anywhere in your code and the bundler will include it when it builds your app for the browser.
And you'll still going to get that error if you don't have a locale for user's language, so you should catch that case:
import(`dayjs/locale/${lang}`).then(
() => {
dayjs.locale(lang);
setAdapterLocale(lang);
},
() => { // in case the import fails
// maybe default to english
dayjs.locale('en');
setAdapterLocale('en');
});
I figured it out. The problem was that when building the package for the .net app, the package was created using rollup (which is not the case when running in browser).
Rollup needs some special config to support dynamic import:
https://www.npmjs.com/package/#rollup/plugin-dynamic-import-vars

MUI Property 'palette' does not exist on type 'Theme'

I am using MUI with typescript. And I keep getting this error
Property 'palette' does not exist on type 'Theme'.ts(2339)
Here is the code
const StyledTextField = styled(TextField)(({ theme }) => ({
backgroundColor: theme.palette.primary.main,
}));
But when I console.log the theme variable, it displays an object with the paletteproperty.
{palette:...}
Why is typescript showing this error, when the object has the properties? what type should I make the theme variable for the compiler to pass?
I tried to simlate your issue and i only could get this error if I import styled from #mui/styles or #mui/styled-engine.
Styled should be import from #mui/material/styles, as you can see here. So, the code will be like:
import { styled } from "#mui/material/styles";
Regarding the difference of the both imports, according to Mui docs:
#mui/styled-engine:
#mui/styled-engine - a thin wrapper around emotion's styled() API, with the addition of few other required utilities, such as the <GlobalStyles /> component, the css and keyframe helpers, etc. This is the default.
* Basically it wont work with other #mui libraries, like ThemeProvider.
#mui/material/styles:
All the MUI components are styled with this styled() utility. This utility is built on top of the styled() module of #mui/styled-engine and provides additional features.
And styled imported from #mui/material/styles use styled code from #mui/styled-engine as base, implementing features and making it possible to work and handle with other #mui librarys such as ThemeProvider and createTheme.
You can check the difference of both implementation below:
from #mui/material/styles
from #mui/styled-engine

reactjs in VSCode: how to find out all scripts that imported component from current script?

I'm new to using VSCode and the programming language reactjs, so excuse me if this is obvious. I'm troubled with the following situation:
In many reactjs projects, the component defined in a .js file is imported in another script under a different name.
Sometimes, the component defined in a .js file are not even exported with a name. E.g. export default {...} or export default (...) => {... some code ...}
How do I find all the occurrences of the component throughout the project in these situations?
What I need is a method or tool that can locate all places where the component is imported/used, since doing a "global search" on the name with "Match Case" and "Match Whole Word" is not useful at all in these situations. 1. It is imported under a different name, so knowing the export name is not useful; 2. It has no name to start the search.
Its the feature of the library react.js that you can export a component by its name or by using the keyword 'default';
1): If you export a component by the keyword 'default' with the name of the component besides default than you can use it in any other script by importing any name e.g export default AppBar than import App from './AppBar'
2): If you just export the component by not giving it the name than it will be an anonymously exported function which you can named anything while importing it in any other script
To expand on what Saima Ashraf already said:
Naming Components
When you create a React Component, I would highly recommend to give it a name, best practice it is the same name as the file name, for example:
Navbar.js
export default Navbar() {
return (
<ul>
<li>Home</li>
<li>About</li>
</ul>
)
}
And in another file you import it with the name you have given it.
// Layout.js
import Navbar from "./Navbar";
export default Layout() {
return <Navbar />
}
When creating new Components, they always should have a descriptive name of what they do.
How to find the components
VS Code
In VS Code on the left sidebar, you have a search function. It is the Magnifying glass Icon. You can write the name of your component and activate the settings "Match Case" and "Match Whole Word". SO if you were to search for "Navbar" you would get all the files that have Navbar used as a word in the file, which is usually the component being used.
React Dev Tools
You can also install the React Dev Tool extension on your browser with which you can check out the component tree being used. It also has a search function, so you can search for a specific component like "Navbar".

how to compile time check strongly typed props in vue templates?

Using Vue with Typescript makes it possible to specify types for props: Strongly typing props of vue components using composition api and typescript typing system
However, as far as I can see these props are only checked at runtime. Here's a simple example component. It has two props a, and b. One is a number and the other a string. Additionally b has a validator, it is only valid if it's equal to hi
<template>
<p>{{a}}</p>
</template>
<script>
import {defineComponent} from 'vue';
export default defineComponent(
{
name: "TestComp",
props:{
a:number,
b:{
type: String,
validator:(val)=>val=="hi"
}
}
}
)
</script>
Here's how you could (incorrectly) use the component. The prop a has a wrong type and the prop b fails its validation:
<TestComp a="hi" b="ho"/>
Is it possible to find this bug at compile time?
Out of the box, Vue only complains at runtime, with a message such as Invalid prop: custom validator check failed for prop "b".
After searching online, I found that prop type validation can be switched on as an experimental Vetur feature. But this doesn't call the custom validator, so in the example above, Vetur can't find the problem for b.
Also, I'm not always using Vetur and would prefer to have the wrong types trigger an actual compile time error.
For (a): Type definitions
The Typescript / Vue Template compiler does not check for this.
Why? Because the type information is not available to the template compiler.
It is possible to analyze this outside the "normal" template compiler. WebStorm has a check for this.
For (b): Validator
The validation is done at runtime and cannot be checked at compile time.
You can write many of those assertions by adding the exact type to the prop, then WebStorm can check them. When using type checks, it is best use typescript (although you can use /** #type */ comments, too)
<script lang="ts">
import {defineComponent} from 'vue';
export default defineComponent(
{
name: "TestComp",
props:{
b:{
type: String as PropType<"hi">,
validator:(val)=>val==="hi"
}
}
}
)
</script>
Try vue-tsc. It's a part of Vite vue-ts preset that allows to check Vue templates on compile. I was going to use Vite along with Webpack just for templates type checking, but it seems like vue-tsc can do it by itself. However Vite CLI makes configuration easier as it provides all the base TS config, so we only need to compare with already existed tsconfig and take what we need.

Flickity via webpack returning different result

I am installing Flickity using npm: npm i flickity.
Flickity version is 2.2.0
Then I call and use like this:
import Flickity from 'flickity'
const flickity = new Flickity(el, options)
console.log(flickity)
I have checked the function Flickity and realize that it is minified after building via webpack, and it seems to return the different result for flickity object. Therefore, it causes the action/methods on flickity object to behave differently. Please see the attached screenshot below for better illustration:
Development environment:
Minified via webpack:
Could anyone give suggestions on what is wrong in my situation to fix this issue?
Update: One important piece of information I haven't mentioned is that flickity object is initialized inside a vue component. It might be the reason for this problem.
carousel.vue
import Flickity from 'flickity'
export default {
data () {
return { options } // options object
}
mounted () {
this.instance = new Flickity(this.$el, this.options)
console.log(this.instance)
}
}
I am using vue 2.6.10. The result this.instance is different on the two environments as I stated above. I still need help on this issue.
The right syntax is:
import Flickity from 'flickity';
EDIT:
It seems to work correctly, take a look at my snippet (I've used a react template but also plain es6 should be fine)

Categories