WebStorm 2021.3 shows "Unresolved variable $sdk" when accessing Nuxt.js plugin from component - autocomplete

I'm trying to use Nuxt.js plugins within my project, but WebStorm is not able to correctly recognize what the plugin exposes.
In my case, it's an OpenAPI client, and without autocompletion in WebStorm, I am pretty much unable to work with it at all, without looking up every endpoint manually.
To visualize the problem, I've created a fresh project as a reproducer.
https://github.com/mklueh/nuxt-plugin-webstorm-autocomplete-reproducer
The plugin simply exposes a demo function, that I try to access from a component.
my.plugin.js
export default async ({app}, inject) => {
inject("sdk", {
"thisIsATestMethodThatShouldBeRecognized": function () {
return "hello from plugin";
}
})
}
component
For whatever reason, I cannot enable Node.js coding assistance in this reproducer project, but in my real project, it is enabled. So I'm not sure if this is related and cause of the issue.
How can I ensure, that WebStorm finds what Nuxt.js plugins expose?

It turns out you have to use Vue.prototype explicitly to register $sdk to the global Vue context.
Changing my plugin to this does the trick
import Vue from "vue";
export default async ({app}, inject) => {
const plugin = {
"thisIsATestMethodThatShouldBeRecognized": function () {
return "hello from plugin";
}
};
Vue.prototype.$sdk = plugin;
inject("sdk", plugin);
}

I've just faced this issue and it's really annoying. I looked inside the .nuxt folder to see how plugins are injected and this is what I found:
export default async ({app}, inject) => {
const sdk = {
"thisIsATestMethodThatShouldBeRecognized": function () {
return "hello from plugin";
}
}
app.$sdk = sdk
inject("sdk", sdk)
}
tested on WebStorm 2021.3.1

Related

"Import" doesn't work on the spec file on Cypress

If someone could help me on this please.
I have created page objects with the following code:
class Login {
username(){
return cy.get('#UserName').type('test1')
}
password(){
return cy.get('#password-field').type('test2')
}
loginbtn(){
return cy.get('.btn').click()
}
}
export default Login
Here I have created class Login and imported on the spec file as:
import Login from '../support/PageObjects/Login'
beforeEach('Login to shipment page',() => {
cy.Login()
})
This was working before but now this is not working and I get the error (on hover) telling "Login is declared but it's value is never read." I have changed nothing. I am facing this issue many times but never got the proper solution for this.
The login is not needed to be imported when you have a custom command like cy.Login().
That is why the error occurs:
'Login' is declared but it's value is never read.
Custom commands are global to all tests and never need importing. The Login page is being added to the tests via cy.Login() and you can remove the import without affecting it.
This has to be something to do with your custom command cy.Login(), I imagine the code for it to be something like below:
// cypress/support/commands.js
const login = new require('../PageObjects/Login.js')
Cypress.Commands.add('Login', () => {
login.username()
login.password()
login.loginbtn()
})
Now that of course needs to be imported into cypress/support/e2e.js, but that is the default - check it anyway.
// cypress/support/e2e.js
import './commands.js'
If you are using the Typescript, options are similar.
By the way, what is the file you are having the error from? I suspect that will give a clue.
You have to create an object of the class Login and using that you can access the different methods. So your code should look like this:
import Login from '../support/PageObjects/Login'
const login = new Login()
beforeEach('Login to shipment page', () => {
login.username()
login.password()
login.loginbtn()
})

Flutter - How use conditional compilation for platform (Android, iOS, Web)?

I am creating a mobile app in Flutter. Now I have a problem, for one platform I will use a plugin for another, I need to write my platform code (the implementation of the plugin is not suitable).
I see several solutions:
It would be optimal to create several projects and use conditional compilation and shared files in them. I used this technique in visual studio. but I am now using android studio. there is no project file, only folders.
Also a problem with conditional compilation support. I found this article and conditional compilation is very limited.
create your own plugin and use it fully. but it is more labor intensive.
What do you advise maybe there is a third way?
When working with multiple environments (eg. IO and Web) it might be useful to add stub classes to resolve dependencies at compile time, this way, you can easily integrate multiple platform dependent libraries, without compromising compiling for each of it.
For example, one can have have a plugin structured in the following way:
- my_plugin_io.dart
- my_plugin_web.dart
- my_plugin_stub.dart
- my_plugin.dart
Let's break it down, with a simple example:
my_plugin.dart
This is where you can actually have your plugin's class to be used across multiple projects (ie. environments).
import 'my_plugin_stub.dart'
if (dart.library.io) 'my_plugin_io.dart'
if (dart.library.html) 'my_plugin_web.dart';
class MyPlugin {
void foo() {
var bar = myPluginMethod(); // it will either resolve for the web or io implementation at compile time
}
}
my_plugin_stub.dart
This is what will actually resolve at compile time (stubbing) to the right myPluginMethod() method.
Object myPluginMethod() {
throw UnimplementedError('Unsupported');
}
And then create the platform implementations
my_plugin_web.dart
import 'dart:html' as html;
Object myPluginMethod() {
// Something that use dart:html data for example
}
my_plugin_io.dart
import 'dart:io';
Object myPluginMethod() {
// Something that use dart:io data for example
}
Other official alternatives may pass from creating separated projects that share the same interface. This is just like Flutter team has been doing for their web + io plugins, resulting in a project that can be bundled with multiple projects:
- my_plugin_io
- my_plugin_web
- my_plugin_desktop
- my_plugin_interface
A good article explaining this may be found here.
Just typed it right here in SO, so I'm sorry if I had some typo, but you should easily find it on an editor.
You just need to import:
import 'dart:io';
And then use conditionals based on:
// Platform.isIOS // Returns true on iOS devices
// Platform.isAndroid // Returns true on Android devices
if (Platform.isIOS) {
navigationBar = new BottomNavigationBar(...);
}
if (Platform.isAndroid) {
drawer = new Drawer(...);
}
Add this library (no package needed)
import 'dart:io' show Platform;
Now you can create a function that checks which platform the user is using.
Widget getWidgetBasedOnPlatform() {
if (Platform.isIOS) {
return Container(); //the one for iOS
}
else if (Platform.isAndroid) {
return Container(); //the one for Android
}
}

How to fix this warning "useLayoutEffect" related warning?

I am using NextJS with Material UI and Apollo. Although, everything is working properly but the warning is not going. It seems to me that a lot of Material UI components are using useLayoutEffect which is warned by React. The error is below.
Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See fb.me/react-uselayouteffect-ssr for common fixes.
The problem is solved. I was suspecting it occurred for Material UI but it is actually happening for Apollo. I am posting the solution here to let others know.
in Apollo configuration file I needed to say the application is using Server Side Rendering. Please check the code below. If you are not using TypeScript then just remove the Types. In the last line { getDataFromTree: 'ssr' } object solved the issue. I hope it will help you.
import { InMemoryCache } from 'apollo-cache-inmemory';
import ApolloClient from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import withApollo from 'next-with-apollo';
type Props = {
ctx?: {};
headers?: {};
initialState?: {};
};
const createClient = ({ ctx, headers, initialState }: Props) =>
new ApolloClient({
cache: new InMemoryCache().restore(initialState || {}),
link: createHttpLink({ uri: process.env.API_ENDPOINT })
});
export default withApollo(createClient, { getDataFromTree: 'ssr' });
I had the same problem using jest, enzyme and Material UI, but I was not using Apollo. If you encounter this problem using Material UI, a simple work around is to add to your test config file (src/setupTests.js) the following:
import React from 'react';
React.useLayoutEffect = React.useEffect;
Sources: here and here and here.
Otherwise, if your stack includes Apollo, you could try

Why is ic-ajax not defined within certain functions in Ember CLI?

Forgive my ignorance, but I can't get ic-ajax working inside of certain
functions.
Specifically, I'd like to get a test like this working, but for Ember CLI:
e.g. http://coderberry.herokuapp.com/testing-your-ember-application#30
I can call ajax inside Ember.Object.Extend and outside of functions and object definitions, but not in modules, tests, or Ember.Route's model function.
Am I misunderstanding something or is there a misconfiguration in my app?
I've figured out that within functions I can do:
ajax = require('ic-ajax')['default'];
defineFixture = require('ic-ajax')['defineFixture'];
but I'm pretty sure import at the top of the file is supposed to work.
I'm experiencing this on Ember 0.40.0 (both in my existing app and a fresh app). See below for more specifics where I'm finding it undefined. Setting var ajax = icAjaxRaw outside of the functions does not work either. I'm at a bit of a loose end so any help you could give in this regard would be great.
users-test.js:
import ajax from 'ic-ajax';
import { raw as icAjaxRaw } from 'ic-ajax';
import { defineFixture as icAjaxDefineFixture } from 'ic-ajax';
debugger;
---> icAjaxDefineFixture IS defined here
module('Users', {
setup: function() {
App = startApp();
debugger;
icAjaxDefineFixture --> UNDEFINED
},
teardown: function() {
Ember.run(App, App.destroy);
}
});
test("Sign in", function() {
icAjaxDefineFixture --> UNDEFINED
expect(1);
visit('/users/sign-in').then(function() {
equal(find('form').length, 1, "Sign in page contains a form");
});
});
Brocfile.js (I don't think these are actually needed with the new ember-cli-ic-ajax addon):
app.import('vendor/ic-ajax/dist/named-amd/main.js', {
exports: {
'ic-ajax': [
'default',
'defineFixture',
'lookupFixture',
'raw',
'request',
]
}
});
Had the same problem. Turns out it is a Chrome debugger optimization issue, checkout this blog post http://johnkpaul.com/blog/2013/04/03/javascript-debugger-surprises/
While debugging, if you try to use a variable from a closure scope in the console, that wasn’t actually used in the source, you’ll be surprised by ReferenceErrors. This is because JavaScript debuggers optimize the hell out of your code and will remove variables from the Lexical Environment of a function if they are unused.
To play around in debugger, I've just typed ajax; inside of the closure and variable magically appeared.

Test if an add-on sdk firefox extension is installed

my question is in the subject.
I need to be able to test if my add-on sdk based extension is installed in order to open it programmatically.
How would I do that ?
Basically, I have a JS script checking for the web browser of the user and if my extension is installed, I'd like to redirect to a specific url, which will launch the opening of the extension.
I read that with XUL extension, adding a contentaccessible=yes to any image and testing it onload gives us the answer, but it seems we can't do that with add-on sdk based...
Any idea ?
Thanks anyway for reading me :)
You should look at the docs for the AddonManager:
https://developer.mozilla.org/en-US/docs/Addons/Add-on_Manager/AddonManager
Here is a code snippet that you coulde use to get going:
const { Cu } = require("chrome");
let AddonManager = Cu.import("resource://gre/modules/AddonManager.jsm").AddonManager;
AddonManager.getAddonsByTypes(["extension"], function(addons) {
var addonData = [];
for (let i in addons) {
let cur = addons[i];
addonData.push({
id: cur.id.toString(),
name: cur.name,
});
};
console.log(JSON.stringify(addonData, null, ' '));
});
I've hosted this code on the Add-on Builder as well:
https://builder.addons.mozilla.org/package/44810/latest/
Edit: Builder is EOL and will go offline in a month.