-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optional chaining in templates does not seem to work #11088
Comments
As said in the release notes:
|
ah derp, totally read over that comment |
Technically, to support such syntaxes in Vue 2, we need to:
We don't have the capacity to implement it yet. But contributions are welcome. |
Potential workaround includes using lodash's get as stated in #4638 (comment) Another hack is to use As i.e.
Example template
Although its still no substitute for the real operator, especially if you have many occurrences of it |
@McPo Just how safe do you think this is? I'm about to use it in production code because I do not want to set computed properties for the numerous nested fields that may be |
As far as Im aware, it should be fine, as youre in control of the input. The only issues would be if the developer wasnt aware that its using eval and allows user input to it, but that doesn't really make sense in the case of the elvis operator. It may have a performance impact though, in that Vue will probably recall the method on every update. I would also suspect theres some overhead in calling |
Please do not use A better way to access properties in a fail-safe way (like with optional chaining) is the following:
The |
True I forgot to highlight the issue that it requires optional chaining to be supported in the browser. (Which isn't a major issue in my case, although I probably will stop using it anyway) |
For deeply nested complex objects, this seems really important. I have objects that are five layers deep. I like the getSafe() method described by troxler, but I would prefer that chaining just work. |
Using the following for a TS project:
with VUE expressions that look like:
Gets a bit nesty beyond the first property, but the linters are happy. |
@tvkit that's not exactly good implementation as it won't work with any other |
Using a function is outside the scope of this issue and not a viable replacement. However if someone need this kind of hack, use this 👇 const reducer = source => (object, property) => object?.[property] ?? undefined
const optional_chain = (...parameters) => {
const [source, ...properties] = parameters
return properties.reduce(reducer(source))
} <div :foo="optional_chain({}, 'foo', 'bar', 'baz')" /> |
@Juraj-Masiar Good point. |
@Sceat I actually really like the idea. |
I guess the idea is to use optional chaining in Single File Components. But, funny enough, if you import the template from an HTML or PUG file, it works. I'd guess it shouldn't work either. |
Please stop 🛑 the discussion about whether this feature is wanted or not. I'm nut sure if we want to support it in Vue 2... I understand this. But in Vue 3 this is an essential need. (if not already possible, I'm sadly a bit behind due to lacking support of |
One more way to do this, didn't want to use lodash. Add a mixin / function Vue.mixin({
methods: {
$get(obj, path, defaultValue = null) {
let result = obj;
for (let piece of path.split('.')) {
result = result[piece];
if (!result || typeof result !== 'object') {
return result || defaultValue;
}
}
return defaultValue;
}
}
}); Use in templates <template>
<p>{{ $get(company, 'representative.address.street', '(No address)') }}</p>
</template> May not (probably does not) work for all scenarios, but helped me move on. Later I'll search replace with |
This works, thanks a lot! The only reply that didn't suggest various hacks and workarounds. |
Let's support this issue to implement it in vite & vue 2 underfin/vite-plugin-vue2#161 |
In the file node_modules\vue-template-babel-compiler\lib\index.js 184 line find |
The blog post on Vue 2.7 https://blog.vuejs.org/posts/vue-2-7-naruto.html says:
Will this release solve this? |
@robert-niestroj I tested this today and it seems to work in v2.7 (make sure you have vue-loader >=v15.10 installed) |
Be aware that you can't use typescript there with Vue 2.7. |
I tested it today with Quasar Framework 1.19.4, based on Vue 2.7.1 and can confirm it works. |
I'm gunna go ahead and close this issue for now since there is a solid solution, upgrading to v2.7 should be pretty easy for most users. |
@DRoet updating vue to
Did you configure something in webpack? |
Sadly plugin above did not help at all for chaining. To update from 2.4 to 2.7 and webpack from 3 to 4 with babel to 7 seems like one month job alone on my project T.T . I wish there would be some easy solution :( , like on vue 1 project it worked just like that with no changes needed :D . For now using function above, tnx at least for that! |
Just migrate to each minor version instead of doing a big jump. |
Plugin did not work because it needs vue-loader 15, but jump from 14 to 15 has so many bcbreaks that after day I was lucky to even be able roll back to working solution :D . For webpack 3 to 4 is much much worse, I have all minors at max, but when doing big jumps there are just too many bc-breaks, its old project and it show like hundreds of errors :) . At times like this, just miss vue 1, where chain work just like that :-) . |
Vue-CLI 4 + Vue 2.7 I am not able to get Here is a simplified version of my deps: "dependencies": {
"vue": "2.7.11",
"vue-router": "3.6.5",
"vuex": "3.6.2"
},
"devDependencies": {
"@babel/core": "^7.19.3",
"@babel/eslint-parser": "^7.19.1",
"@babel/runtime": "^7.19.4",
"@vue/cli-plugin-babel": "^4.5.19",
"@vue/cli-plugin-eslint": "^5.0.0-rc.2",
"@vue/cli-plugin-router": "^4.5.19",
"@vue/cli-plugin-vuex": "^4.5.19",
"@vue/cli-service": "^4.5.19",
"@vue/test-utils": "^1.3.0",
"core-js": "^3.25.5",
"eslint": "^8.25.0"
} I removed What do I need to change to allow Optional Chaining in the template? Tagging @DRoet because they closed this in hopes of an answer or re-opening. As this seems like a very common situation (Vue-CLI). |
I had similar problem. Fix for that was configure babel-loader in webpack for js files. Example for my rails app:
|
@maxkopych You showed code, but did not mention what file to put it in. To be clear, I am not using Webpack. I am using Vue-CLI (which in turn handles Webpack for me). So any Webpack tweaks need to be handled via the I'm asking if I need to change something there, and if so, what do I change? |
I didn't work with vue-cli for awhile. But again if you gonna read this article All you need is search how to add new rules to loaders in vue-cli. first that I found: https://stackoverflow.com/questions/59960121/how-can-i-add-new-rules-to-loaders-while-using-vue-cli-3-x |
@TheJaredWilcurt are you using |
Here is my {
"packages": {
"node_modules/@vue/cli-service": {
"version": "4.5.19",
"dependencies": {
"vue-loader": "^15.9.2"
},
"optionalDependencies": {
"vue-loader-v16": "npm:vue-loader@^16.1.0"
}
},
"node_modules/@vue/cli-service/node_modules/vue-loader-v16": {
"name": "vue-loader",
"version": "16.8.3"
},
"node_modules/vue-loader": {
"version": "15.9.8"
}
},
"dependencies": {
"@vue/cli-service": {
"version": "4.5.19",
"requires": {
"vue-loader": "^15.9.2",
"vue-loader-v16": "npm:vue-loader@^16.1.0"
},
"dependencies": {
"vue-loader-v16": {
"version": "npm:[email protected]"
}
}
},
"vue-loader": {
"version": "15.9.8"
}
}
} |
I had same problem and manage to solve it by adding babel plugins:
Just for the info, versions from package-lock (as it is today) are:
As you can see we are still on Quasar 1 and Vue 2, planning move to Vue 3, but not now. |
Can I just check, this wasn't working in the template before (only in script logic), but now it works in the template just fine. Did something change (i'm using v2.6.11)? |
@richard-d-vindico Vue 2.7 added support for using ESNext syntax in template expressions. (https://blog.vuejs.org/posts/vue-2-7-naruto.html) Run |
I'm on v2.6.11 and it's works just fine in the template.
…On Thu, 19 Jan 2023, 00:48 Cameron Wilby, ***@***.***> wrote:
@richard-d-vindico <https://github.com/richard-d-vindico> Vue 2.7 added
support for using ESNext syntax in template expressions. (
https://blog.vuejs.org/posts/vue-2-7-naruto.html)
Run npm ls | grep vue@ to see what your specific version of Vue is.
—
Reply to this email directly, view it on GitHub
<#11088 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AT2ULAKDZ7QF2O44CZP7X5TWTCFMZANCNFSM4KRMZCZQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Version
15.8.3
Reproduction link
https://template-explorer.vuejs.org/#%3Cdiv%20id%3D%22app%22%20v-if%3D%22obj%3F.a%22%3E%7B%7B%20msg%20%7D%7D%3C%2Fdiv%3E
Steps to reproduce
Use a v-if that uses optional chaining w/
@vue/cli version 4.2.0
:v-if="test?.length > 0"
What is expected?
no error is thrown
What is actually happening?
following error is thrown:
The text was updated successfully, but these errors were encountered: