How to extend web3js with TypeScript? - reactjs

So I'm trying to build a prototype on React w/ TypeScript for an application that I'm developing - which in the future I'm going to migrate to Django, that's why I want to use web3js, to pass it later to web3.py - and a I wanna use the relay methods of Infura, so the users don't need to have a cryptowallet.
How I'm trying to do it is by following the Infura tutorial on ITX and getting everything on web3js. Right now what I have is this:
//Configure the provider
let web3 = new Web3(
new Web3.providers.HttpProvider(
`https://:${process.env.REACT_APP_PROJECT_SECRET}#${process.env.REACT_APP_ETHEREUM_NETWORK}.infura.io/v3/${process.env.REACT_APP_PROJECT_ID}`
)
);
web3.extend({
property: "relay",
methods: [
{
name: "getBalance",
call: "relay_getBalance",
params: 1
},
],
})
This is what I do at the start of the React component. Later, I wanna have a callback that, when I want, it'll retrieve the balance of the gas pool so it'll be something like:
() => web3.relay.getBalance(...)
The problem is that, when I try to use it like that, as the property doesn't exist on the Web3 class, I can't compile it. Is there a way to extend the class definition so I can define - and use - the relay methods inside its own module? I've tried with JS and works fine, but I would really like to keep the project on TS.

Related

Typescript + React - Get the type of a variable from its type

New to Typescript and unsure on how to achieve this.
I'm using React to build a component - a table - using this library https://devexpress.github.io/devextreme-reactive/react/grid/docs/guides/getting-started/
Say I have some service that gets some data:
const { data, error, loading, refetch } = songService.get(queryOptions);
I want to call this service in the table component itself, however I don't want it to be restricted to only getting data from the songService. I'd like to get it from whatever service I pass in the props - so I'm thinking:
<DXTable serviceFromData="songService" /> or <DXTable serviceFromData="coverService" />
However I have 2 questions/uncertainties:
- What type would the serviceFromData prop be? I'd like it to be generic.
- How do I ensure my const queryOptions has a specific interface based on the service?
Any help would be appreciated.
Thanks.
I would create an interface for each service and have them extend a common interface.
From here you have two options:
1. serviceFromData can take the type of the common interface so it somewhat generic
2. serviceFromData can take a type like Service1 | Service2
You can ensure the queryOptions to be a specific interface by adding the desired type to the get() method like get(queryOptions:SomeInterface)in your service classes.

Sharing data (an array) between two screens in tabs view using react-navigation in react native

I am using react-navigation without redux. so i have two tabs each with their own stack navigator, having one screen each. so i need and array of locations in both screens. currently i am doing this in both screens:
state = { locations: [] };
componentDidMount() {
this.getAllLocations();
}
async getAllLocations() {
let locations = await this.getMoviesFromApi();
this.setState({ locations });
}
i just want to have this array at one location and both components should share this single source of truth. so changes made by either screen is reflected in the other screen. Is this possible without redux?
RN 0.59 has opened great possibilities with its release. One of them are react hooks, which is available in the latest version... in the future react hooks will be used everywhere. Trust me. So, a while back I looked for the possibilities of having a global state using react hooks and found the reactn library. It uses react native hooks, and even you can use global state in CLASS components. which opens a new door for theming and sharing data. Now my app supports light/dark mode, dynamic font size, Languages, and early implementation of "portals" using only this library.
The best part about it is that you can use it like state. There is no need of provider, or redux stuff (although it provides it). It can be integrated with react navigation (it requires modifying some source code, at most, adding an "n" to react, and reference the global variable). Is awesome and I love it.
I have been thinking in doing an article on medium about this, because the lib is not that popular in RN community, but hope that you will give it a chance the library is only 22KB, less than one full component.
As an alternative, you could think about writing your own library using hooks. But it's gonna be hard. Try it, there is no going back
It is possible if you have a singleton object :
export default class SharedData {
constructor(){
if(SharedData.instance){
return SharedData.instance;
}
this.state = {locations:[]};
this.listners =[];
SharedData.instance = this;
return SharedData.instance;
}
setLocations(locations){
this.state.locations = locations;
this.listners.forEach(listner=>listner(this.state.locations));
}
getLocations(){
return this.state.locations;
}
addListner(listner){
this.listners.push(listner);
return listner;
}
removeListner(listner){
let index = this.listners.indexOf(listner);
if(index > -1){
this.listners.splice(index,1);
}
}
}
and then in every tab where you want to access shared locations state:
// get an instance of SharedData
this.sharedData = new SharedData();
// subscribe to locations changes
this.listner = sharedData.addListner((locations)=>{
this.setState({locations});
});
// set locations
this.sharedData.setLocations([]);
// unregister when destroying the component
this.sharedData.removeListner(this.listner);
I guess in order to achieve your goal, you're going to need some sort of a mechanism for storing 'global data', and if you don like Redux because it requires a lot of setup to achieve this simple task of sharing global data, then you chould you unstated ... which is alot simple to setup

ReactJS external library

Hi I am quite new to reactjs but I started to understand few things. But this one giving me a headache, I have a small reactjs component that will be added in an existing site. The problem is inside my component I wanted to use a function in a JS file that is declared masterpage of the site. The name of the function I want to access is "SPClientPeoplePicker_InitStandaloneControlWrapper", so whenever I build my component I get the following error :
'SPClientPeoplePicker_InitStandaloneControlWrapper' is not defined no-undef
I tried using windom.SPClientPeoplePicker_InitStandaloneControlWrapper but the problem is in window "SPClientPeoplePicker_InitStandaloneControlWrapper" is giving me a different function. It would be nice if that library can be scoped inside my component
I tried calling library using import but it didnt work
import clientforms from "https://standardsSite.com/_layouts/15/clienttemplates.js";
I solve the problem I use loadjs its very handy.
loadjs(
[
"https://mysharepointsite.com/_layouts/15/clienttemplates.js",
"https://mysharepointsite.com/_layouts/15/clientforms.js",
"https://mysharepointsite.com/_layouts/15/clientpeoplepicker.js",
"https://mysharepointsite.com/_layouts/15/autofill.js"
],
"SPLibrary"
);
let self = this;
loadjs.ready("SPLibrary", function() {
self.handleSubmit(self.props.name);
});

Meteor Server-side variable persist between methods

I am building a simple Meteor-Angular 1 application and I am having a trouble to make my variable 'var conn' persist between methods in server.
Meteor code:
import {Meteor} from 'meteor/meteor';
var name;
Meteor.methods({
'setName': function () {
name = 'Harry';
},
'getName': function () {
console.log(name);
});
}
});
If I am calling setName and getName from the same template in Angular then name persists. If I set name in one template but call getName in another template, then name is 'undefined'. I came with Java background and don't know how to make meteor class persist as the same object between Angular templates. Thank you very much for help in advance.
You have 3 options:
Store it in a collection in MongoDB.
Use a global variable defined in a /server/xxx.js file.
Other server side persistence tools. Maybe https://github.com/lmaccherone/node-localstorage?
For alt 2, you could create a dictionary object and scope the data to the client connection by using the connection.id from Meteor.onConnection() [Docs].
i'm surprised it works at all. if that code is indeed running on the server, it's invoked in a new context on each call. if you want your data persisted, you need to persist in the database.

How React Component expose data to external app?

Let's say i have a React Component <forecast id="test"/>. And i want import this component into a legacy project which only have jquery involved.
Is it possible to get the value of this component like document.querySelector('#test').value?
I got some information from React website, that we cannot access data from outside the component. The recommended way is dispatching data from inside of the component.
My question is, the way to dispatching data is behind of the component implementation. Is it means that i have to read the source code of component in case i don't know how it works?
If this is true, i won't think React is free to inject to any product, it cost too much.
If you want to inject some React to your project you should do it with some independent part of your system.
If you have tightly coupled code base its always high cost to add any new technology to it. So its not a React problem. Try to find some independent module or subapplication in your system and move it to React. If you cannot find one, try to refactor existing code first.
You need to write a plain JS wrapper to do it. Something like this might work
function Forecast(element) {
this.value = initialValue;
React.render(<forecast onChange={onChange.bind(this)}/>, element);
function onChange(newValue) {
this.value = newValue;
}
}

Resources