Skip to content

Instantly share code, notes, and snippets.

Created July 12, 2017 22:36
Show Gist options
  • Save anonymous/6e4f27981c7f6d3bbea66919e39f198a to your computer and use it in GitHub Desktop.
Save anonymous/6e4f27981c7f6d3bbea66919e39f198a to your computer and use it in GitHub Desktop.
import { Injectable } from '@angular/core';
import { Http, Headers, Response } from "@angular/http";
import { Observable } from "rxjs";
import Web3 from 'web3'; /** I think this is equivalent
to the require function. I'm also doing 'web3/lib because that is where the web3.js file is*/
let web3:Web3 = new Web3();
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} /** set the provider you want from Web3.providers */
else {
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}
@Injectable()
export class SharedService {
currencyURL = "http://api.fixer.io/latest?symbols=";
totReqsMade: number = 0;
constructor(private _http: Http) {
}
getBalance(Add){
return this._http.get(this.currencyURL + Add)
.map(response => {
{ return response.json() };
})
.catch(error => Observable.throw(error.json()));
}
getEtherBalance(PubAd) {
return web3.eth.getBlock(48, function(error, result){
if(!error)
console.log(result)
else
console.error(error);
})
}
/** let web3 = require('web3'); Trying to instantiate how the website says to do it.*/
}
@DeviateFish
Copy link

I replied on your other one, but I'll paste it here, too:

Oh, I think what might be going is that you're overwriting the global web3 with your local one in this scope.

This line is supposed to be checking to see if web3 is already defined in the global scope, but I think the line before that is breaking it.

I think it should probably be the following (feel free to change variable names):

let localWeb3:Web3;
if (typeof web3 !== 'undefined') {
  localWeb3 = new Web3(web3.currentProvider);
} /** set the provider you want from Web3.providers */
else {
  localWeb3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

Or, if you want to keep the same naming (this one might be better anyway, due to more explicit global scoping):

let web3:Web3;
if (typeof window.web3 !== 'undefined') {
  web3 = new Web3(window.web3.currentProvider);
} /** set the provider you want from Web3.providers */
else {
  web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

Basically, what I think is going on is that your defining web3 in your local scope, then immediately checking to see if it exists (which it will, always), and trying to use the currentProvider from the web3 you just created (that doesn't have a provider yet)

@carlosm2011
Copy link

It gave me the error: Cannot find name 'web3'. for the first one and then the error Property 'web3' does not exist on type 'Window'. For the second one.

@carlosm2011
Copy link

The following seems to have done the job

import { Injectable } from '@angular/core';
import { Http, Headers, Response } from "@angular/http";
import { Observable } from "rxjs";
import Web3 from 'web3'; /** I think this is equivalent
 to the require function. I'm also doing 'web3/lib because that is where the web3.js file is*/

let localWeb3:Web3 =  new Web3();
if (typeof localWeb3 !== 'undefined') {
  localWeb3 = new Web3(Web3.currentProvider);
} /** set the provider you want from Web3.providers */
else {
  localWeb3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

		

@Injectable()
export class SharedService {
	currencyURL = "http://api.fixer.io/latest?symbols="; 
    totReqsMade: number = 0;
	constructor(private _http: Http) {
	}

getBalance(Add){
        return this._http.get(this.currencyURL + Add)
            .map(response => {
                { return response.json() };
            })
            .catch(error => Observable.throw(error.json()));
}
getEtherBalance(PubAd) { 
return localWeb3.eth.getBlock(48, function(error, result){
    if(!error)
        console.log(result)
    else
        console.error(error);

})
    }

/** let web3 = require('web3'); Trying to instantiate how the website says to do it.*/
}

@DeviateFish
Copy link

Interesting. I'm not sure why that would work, actually.

The problem I see are these two lines:

let localWeb3:Web3 =  new Web3();
if (typeof localWeb3 !== 'undefined') {

If you've just defined localWeb3, it will never be undefined. The sample code you've pulled from is not supposed to be checking the variable you just created, but is checking to see if web3 already exists in the global context--and if so, use the currentProvider it holds, rather than spinning up a new one. This is to allow you to easily use an injected web3 context (e.g. Metamask), and then fall back to a standard http/ipc provider (local node) if the injected one doesn't exist.

The second one is probably the preferable one, but it's probably failing because Typescript. That doesn't look like a runtime error, but a compile-time error. Perhaps you can look into how Typescript determines which properties are on window, and add web3 to it?

@carlosm2011
Copy link

carlosm2011 commented Jul 13, 2017

Yeah I'm using Metamask do I need to specify that somehow?
I found this link that talks about adding properties.

@carlosm2011
Copy link

carlosm2011 commented Jul 13, 2017

Ok I figured it out using (<any>window).MyNamespace.

@carlosm2011
Copy link

Now I'm having trouble with these lines

return  this.web3.eth.getBalance(PubAd, function(error, result){
    if(!error)

        /**console.log(String(result));*/
    	console.log(this.web3.fromWei(String(result), 'ether'));
    else
        console.error(error);
})
            .map(response => 
                response.json()
            )

I'm getting two errors

  1. ERROR TypeError: Cannot read property 'map' of undefined.
  2. Cannot read property 'fromWei' of undefined

@DeviateFish
Copy link

Looks like you're having scoping issues... Look into how scoping works in JavaScript

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment