Rollup: make module globally accessible without need to import - rollupjs

I want module sync-fetch to be accessible globally without need to import in each component and be named as simple fetch.
Also I want to extend it with custom method then.
Now in rollup.config.js there are:
export default {
...
output: {
...
intro: `const fetch = require('sync-fetch');
fetch.Response.prototype.then = function(foo) {
return foo(this);
}`
},
};
And it works, but looks dangerous) Is intro is the only way to do it?

If you want to make it seem less dangerous, you could put that code in a file and then return the contents of it in a function. The output.intro option also takes a function that returns the code as a string.
{
output: {
intro: () => require('fs/promises').readFile('path/to/the/file.js', 'utf-8')
}
}

Related

Vaadin 14: sending data from a web component to server

How can i send data from client to server using html5 webcomponent
setting up data from server to client, is very easy, works like a charm
how ever cannot find solution to send data to server
Please assist, but Iam not going to use Lit or Polymer
#JavaScript
class SimpleComponent extends HtmlElement {
connectedCallback() {
this.innerHTML = '<input type="text" id="test"/>";
this._input = this.querySelector('#test');
this._input.onchange = function() {
***** i want to send the value to server ****
})
}
setInputValue(value) {
this._input.value = value;
}
}
customElements.define("simple-com",SimpleComponent);
Now Java at Server
#Tag("simple-com")
class SimpleComponent extends Component {
public SimpleComponent() {
}
public void setValue(String value) {
getElement().callJsFunction("setValue",value);
}
}
The main challenge compared to Polymer or LitElement is that an event handler defined using the pattern innerElement.onchange = function() {} will not be run with this referencing the custom element instance. This in turn means that trying to use this.$server won't work because this isn't pointing to the expected value even though $server is indeed present in the place where it's supposed to be.
The easiest way of fixing this is to change the code to use an arrow function (() => {}) instead of an explicit function. This works because arrow functions inherit this from the scope where the function is defined whereas explicit functions have this defined in different ways depending on how it is run. Another approach would be to store a reference to this in a separate variable (e.g. let root = this) and then reference that variable instead of this in the function (e.g root.$server.doSomething()).
Putting everything together, this is what the code looks like with my modifications to make everything work.
class SimpleComponent extends HTMLElement {
connectedCallback() {
this.innerHTML = '<input type="text" id="test"/>';
this._input = this.querySelector('#test');
this._input.onchange = () => {
this.$server.handleChange(this._input.value);
};
}
setValue(value) {
this._input.value = value;
}
}
customElements.define("simple-com", SimpleComponent);

angular 11 display static text to dynamic value

I'm having 2 JSONs. The first one is having the format of the JSON value and the second one is having the actual value which is I want to display in the UI.
But I'm seeing the "application.appID" instead of 101. Does any help please?
Not working if label:"applicaiton.appID". I'm having label: "string"
working if label: applicaiton.appID
component.ts
this.json1={
label:"applicaiton.appID"
};
this.application ={
appID:101
};
ui.html
<mat-label> {{json1.label}} </mat-label>
<mat-label [innterHtml]="json1.lable"> </mat-label>
If I understand right, what you're trying to do is to interpolate based on a string expression coming from a json. This is not something that you can do by just using the {{ }} construct. Here's why:
(For simplicity I will use div instead of mat-label)
In theory, this line would solve your problem
<div>{{this[json1.label]}}</div>
Just that it doesn't work since the inner json1.label part is not expanded/evaluated as expected.
Even if we manually write it as an explicit string, it still doesn't give us 101.
<div>{{this['application.appID']}}</div>
The only way to make such a syntax work would be to chain the field indexers, but that doesn't help us with using json1.label as the 'path' of the object and inner field.
<div>{{this['application']['appID']}}</div> // this returns 101, but it's not helpful for us...
So as you can see, pure html interpolation can't really help us achieve our goal. Instead, we should create a helper method inside the .component.ts file:
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
json1 = {
label: 'application.appID'
};
application = {
appID: 101
};
accessPropertyByString(path: string): any {
let result = this;
const parts = path.split('.');
for (const part of parts) {
if (part in result) {
result = result[part];
} else {
return null;
}
}
return result;
}
}
The new accessPropertyByString() method can be now used in the html template like this:
<div>{{accessPropertyByString(json1.label)}}</div>
Which finally returns 101 as expected.

Is it possible to 'assert' a type using .where()?

I have a list<Components> components; which is sub-class of Bonus, hence Bonus are Components too.
The .toRect() method is defined in the Bonus class but not in the Components class.
I'm making sure I'm only calling .toRect() in Bonus objects, so there should be no problem, but Dart is keeping me from running the code with the following error:
The method 'toRect' isn't defined for the type 'Component'.
Is there a way to go around this problem without the need to define .toRect() on the Components Class?
void checkForCollision() {
controller.components.where((c) => c is Bonus).forEach((bonus) {
if (this.toRect().contains(bonus.toRect().topLeft) ||
this.toRect().contains(bonus.toRect().topCenter) ||
this.toRect().contains(bonus.toRect().topRight)) {
this.remove = true;
}
});
}
Could do:
.forEach((bonus) {
Bonus bonus = bonus;
.....
or
(controller.components.where((c) => c is Bonus) as List<Bonus>).forEach((bonus) {
Use whereType to filter on types. It's like where that just checks for a type, but it also ensures that the resulting iterable has that element type.
controller.components.whereType<Bonus>().forEach((bonus) {
... bonus.toRect ...
});
The Dart style guide recommends not using a function literal with forEach, use a for-loop instead:
for (var bonus in controller.components.whereType<Bonus>()) {
... bonus.toRect ...
}
If you are doing that anyway, you can also just do:
for (var component in controller.compenents) {
if (component is Bonus) {
.. component.toRect ...
}
}
The type promotion from the is check will ensure that you can call toRect.
This very directly specifies what's going on, without creating unnecessary intermediate iterables.

Why are my generator methods not inherited?

I'm trying to make a generator that I can then extend to form similar sub-generators
Here's my base generator:
var generators = require('yeoman-generator');
var VolumeAdderBase = module.exports = generators.Base.extend({
initializing: function() {
/* ... */
},
prompting: function () {
/* ... */
},
writing: function () {
/* ... */
}
});
Here's an example sub-generator:
var VolumeAdderBase = require('../../utils/VolumeAdderBase.js');
// console.log(VolumeAdderBase);
module.exports = VolumeAdderBase.extend({
fileType: "tomcat script",
containerName: "tomcat",
containerVolumeLocation: "/opt/tomcat/client-conf/"
});
When I try to run my sub-generator, it does nothing at all. No errors, no nothing.
When I dump the VolumeAdderBase object, there are plenty of methods on there, but they are all the Base ones. The ones defined in VolumeAdderBase are missing.
Am I missing something here? Or is there a better way to create similar sub-generators?
yeoman-generator is only going to run top level methods (Object.getOwnPropertyNames(prototype)). It doesn't go deeper in the prototype; that's by design. If Yeoman was to dig in the prototype, you couldn't use methods like this.destinationPath() or any other helpers as they'd all be schedule to be run - which would just break.
We have plans to support mixin in the future. But that's not currently the case.
As a fix, you can manually assign these methods:
VolumeAdderBase.prototype.prompting = VolumeAdderBase.prototype.prompting;
// etc...

Is there a way to dynamically call a method or set an instance variable in a class in Dart?

I would want to be able to do something like this with a Dart class constructor:
class Model {
// ... setting instance variables
Model(Map fields) {
fields.forEach((k,v) => this[k] = v);
}
}
Obviously, this doesn't work, because this doesn't have a []= method.
Is there a way to make it work or is it simply not "the dart way" of doing things? If it's not, could you show me what would be the right way to tackle this?
You can use Mirrors:
InstanceMirror im = reflect(theClassInstance);
im.invoke('methodName', ['param 1', 2, 'foo']).then((InstanceMirror value) {
print(value.reflectee); // This is the return value of the method invocation.
});
So, in your case you could do this (since you have setters):
import 'dart:mirrors';
class Model {
Model(Map fields) {
InstanceMirror im = reflect(this);
fields.forEach((k, v) => im.setField(k, v)); // or just fields.forEach(im.setField);
}
}
The documentation for InstanceMirror might come in handy.
Currently no. You will have to wait for reflection to arrive in Dart before something like this (hopefully) becomes possible. Until then your best bet is probably to do it in a constructor. Alternatively you could try to use something like JsonObject which allows you to directly initialize it from a Map (for an explanation on how this works, check this blog post).

Resources