Why ionic Network Plugin is not working after upgrading.? - plugins

This code was working fine till upgrade to ionic 3.4.
now in serve command shows :
Property 'connection' does not exist on type 'Navigator'.
I've replaced this code Network.connection with navigator.connection but still the same result.
export class NetworkService {
onDevice: boolean;
constructor(public platform: Platform , private Network: Network){
this.onDevice = this.platform.is('cordova');
}
isOnline(): boolean {
if(this.onDevice && Network.connection){
return Network.connection !== Connection.NONE;
} else {
return navigator.onLine;
}
}
isOffline(): boolean {
if(this.onDevice && Network.connection){
return Network.connection === Connection.NONE;
} else {
return !navigator.onLine;
}
}
}

The wrapper around that plugin has changed and doesn't expose a 'connection' property. Instead you need to use 'type' property. Full example available on the ionic documentation here.

Related

Cannot destructure property `interface` of 'undefined' or 'null'

When I do npm run test I get back this error :
Cannot destructure property interface of 'undefined' or 'null'
I've been trying to fix this error for a cupple of days with no result. I've seen in some other posts that it's usually related with compile.js file... I think its all ok so i cannot find the issue.
I'll paste all my code (nottice I'm triyng to work with the very last version of solidity, in order to learn new functionalities... maybe there's my error...)
THANKYOU!!!
My compile.js:
const path = require('path');
const fs = require('fs');
const solc = require('solc');
const lotteryPath = path.resolve(__dirname, 'contracts', 'Lottery.sol');
const source = fs.readFileSync(lotteryPath, 'utf8');
module.exports = solc.compile(source, 1).contracts[':Lottery'];
.sol:
pragma solidity ^0.5.1;
contract Lottery {
address public manager;
address payable [] public players;
constructor() public payable {
manager = msg.sender;
}
function enter() public payable {
require(msg.value > .01 ether);
players.push(msg.sender);
}
function random() private view returns (uint){
return uint(keccak256(abi.encode(block.difficulty, now, players)));
}
function getPlayers() public view returns (address payable[] memory){
return players;
}
function pickWinner() public payable restricted{
uint index = random() % players.length;
address(players[index]).transfer(address(this).balance);
players = new address payable[](0);
}
modifier restricted(){
require(msg.sender==manager);
_;
}
}
TEST:
const assert = require ('assert');
const ganache = require ('ganache-cli');
const Web3 = require ('web3');
const provider = ganache.provider();
const web3 = new Web3(provider);
const { interface, bytecode } = require ('../compile');
let lottery;
let accounts;
beforeEach(async () => {
accounts = await web3.eth.getAccounts();
lottery = await new web3.eth.Contract(JSON.parse(interface))
.deploy({ data: bytecode })
.send({ from: accounts[0], gas: '1000000' });
});
describe('Lottery Contract', () =>{
it('deploys a contract', () =>{
assert.ok(lottery.options.address);
});
});
Heres how I fixed it:
I had the similar error when running 'npm run test'. What seemed to work for me is uninstalling your current version of solc
and running npm install --save solc#0.4.25
make the following amends in your contract and the test will run just fine.
pragma solidity ^0.4.17; //make change here
contract Lottery{
address public manager;
address[] public players;
function Lottery()public{
manager = msg.sender;
} // use this instead of using constructor
function enter() public payable{
require(msg.value>.1 ether);
players.push(msg.sender);
}
function random() private view returns(uint){
return uint(keccak256(block.difficulty, now, players));
} // make change here
function pickWinner()public{
require(msg.sender==manager);
uint index = random() % players.length;
players[index].transfer(address(this).balance);
players = new address[](0);
}
function getPlayers()public view returns(address[]){
return players;
}
}
you might have made this contract amends to make it compilable in remix but V#0.4.17 does not support this.
the same issue occur when i am trying to running a test
you can try two things:
1:try lower version of solidity. maybe V0.4.17 help you
npm uninstall solc //to uninstall existing solc version
npm i --save solc#0.4.17 //to re-install solc with lower version
2: try console.log() statement in compile.js file to check that contract is compiling or not
console.log(solc.compile(source, 1));
if the output is undefined than maybe there is some issue with your contract.
I had the exact same issue. The problem comes with the solidity compiler you are using. In my particular case I was trying 0.5.4 and for some reason I experienced the same error.
"The contract compilation is different in solc 0.5.0 and above"
one possible solution is using a lower solc version: like 0.4.25 (in my case this works fine).
The problem surges when the compilation takes place, the operation returns null, so there isn't any output and that's why you get an error telling you about the null variable.
use this in Lottery.sol :
pragma solidity >=0.4.21 <0.7.0;
contract Lottery {
address public manager;
address[] public players;
constructor() public {
manager = msg.sender;
}
function enter() public payable {
require(msg.value > 0.01 ether);
players.push(msg.sender);
}
function random() private view returns (uint) {
return uint(keccak256(abi.encodePacked(block.difficulty,now,players)));
}
function pickWinner() public restricted {
uint index = random() % players.length;
address(players[index]).transfer(address(this).balance);
players = new address[](0);
}
modifier restricted() {
require(msg.sender == manager);
_;
}
function getPlayers()public view returns(address[]){
return players;
}
}
For anyone having this issue still, make sure to console.log(solc.compile(source, 1))
Issue for me was that I named a contract something different then what I was passing as an input to .contracts[] array.
Make sure name you're passing to .contracts[] equals the name of a contract class, you can get it by consol logging the solc.compile(source, 1).
The problem is not in the js file it's in the .sol file
Make sure that you are using solidity and solc version 0.4.17
Make sure that you are not using any functions of the new solidity version in your old version like constructor
It can be a basic syntax error in your compile.js file or .sol file
Try changing the constructor function to
function Lottery() public(){ }

Ionic view not updating after return from provider promise

I'm very new to Ionic and JS programming in general so please forgive my ignorance. I've been able to get data from other REST providers I've setup and have the updated values display fine. Pretty much copied the code from some other working functions. This time, no matter what I try, nothing will update.
Provider:
return new Promise(resolve => {
this.http.post(this.apiUrl)
.subscribe(res => {
resolve(res);
},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
this.error = {"text":"App error occured."};
console.log('Client-side error occured.');
} else {
this.error = {"text":"Cloud server error occured."};
console.log('Cloud server error occured:'+err);
}
return this.error;
});
});
}
HTML:
<ion-item>
<ion-label stacked>Make</ion-label>
{{vesselData?.make}}
</ion-item>
Function:
vesselData = {"make":""};
updateVesselInfo() {
const data = JSON.parse(localStorage.getItem('userData'));
this.vesselProvider.getVesselData(data.userData.sim).then(vData => {
this.vesselData = vData;
}).catch(console.log.bind(console));
}, (err) => {
console.log("Vessel: ".err);
});
If I log the data returned from the provider in the .then(), it shows the provider returned the correct data. However, it's not updating any of the vesselData variables. Any idea where I'm going wrong here?
So modern way is to provide method in your provider that returns Observable and then in your component you just call this method and subscribe to it to obtain data:
In your provider:
getVesselData() {
return this.http.post(this.apiUrl)
.pipe(
catchError(this.yourErrorHandlerInsideProviderHere)
)
}
Now in your component:
vesselData = {"make":""};
updateVesselInfo() {
this.provider.getVesselData().subscribe( vesselData => {
this.vesselData = vesselData;
})
}
So ideal is to keep error handling inside provider here and within component your methods should be light weight.
This example should work for you as long as you are on Angular 4.3+ using modern HTTP module that comes with it.
Update:
Please ensure you properly bind to template. Here is example:
https://stackblitz.com/edit/ionic-wqrnl4
I skipped the rest call (http), but the principle is the same.

Custom Select() with parameter

UPDATE
As of #NGXS v3.1, they finally introduced arguments into #Selector().
https://www.ngxs.io/concepts/select#lazy-selectors
Examples from the DOCS
First, you define the #Selector "pandas"
#State<string[]>({
name: 'animals',
defaults: []
})
#Injectable()
export class ZooState {
#Selector()
static pandas(state: string[]) {
return (type: string) => {
return state.filter(s => s.indexOf('panda') > -1).filter(s => s.indexOf(type) > -1);
};
}
}
Then you just call it in your '.ts' file
import { Store } from '#ngxs/store';
import { map } from 'rxjs/operators';
#Component({ ... })
export class ZooComponent {
babyPandas$: Observable<string[]>;
constructor(private store: Store) {
this.babyPandas$ = this.store
.select(ZooState.pandas)
.pipe(map(filterFn => filterFn('baby')));
}
}
* From Old Post *
I am trying to create a custom #Select () to be able to drill down a particular tree and return the values dynamically. Getting either undefined or it's not making it (executing)
user.component.ts
const location = 'new york'
#Select(state => UserState.getUserLocationSlots(state, location)) slots$;
user.state.ts
#Selector()
static getUserLocationSlots(state: UserStateModel, location: any) {
console.log(state);
console.log(location); // <-- expecting 'new york', but getting undefined
}
You can achieve this by using crateSelector function from #ngxs/store
In your .state.ts file:
static getLocationSlots(location: string) {
return createSelector([UserState], (state: string[) => {
// logic for filtering your data
// eg.: state.filter(element => element == location)
})
}
In your .component.ts file:
#Select(UserState.getLocationSlots('new york')) slots$: Observable<any>
You can also check here for more details
I don't think it is possible to pass parameter to #Selector() decorated functions in ngxs v2. It would be nice though.
A ticket exist for this feature request.
Also, I think you are not using #Selector() correctly. I should be something like (hence, cannot pass parameters):
#Select(UserState.getUserLocationSlots) slots$
Refer to the docs.
Note: I am not an expert in ngxs...this is just based on what I understand now.
This is achievable in NGXS v2 & v3. Copied from my comment in the discussion on dynamic selectors here
We can achieve this at the moment using a pattern often used for redux
selectors...
The #Selector decorator can be written so that it returns a function
with the desired parameter. This enables the desired dynamic selector
arguments as well as late resolution of the selected state. For
Example:
#State<UserStateModel>( ... )
export class UserState {
#Selector()
getFilteredUsersFn(userStateModel: UserStateModel) {
return (filter: string) =>
userStateModel.users.filter((user) => user.indexOf(filter) >= 0);
}
}
And then the component would contain:
#Component({...})
export class AppComponent {
#Select(UserState.getFilteredUsersFn)
filteredUsersFn$: Observable<(filter: string) => User[]>;
get currentFilteredUsers$() {
return this.filteredUsersFn$
.pipe(map(filterFn => filterFn('myFilter')));
}
}
To pass parameters you can have the select return a function, it isn't elegant, however it works.
For example the select statement would look like:
#Selector()
static getItemByIdFn(state: { [id: number]: Entity }) {
return (id: number) => {
return state[id];
};
}
then in the component:
this.store.select(MyState.getItemByIdFn)
.pipe(map(mapByIdFn) => mayByIdFn(1)) // using the returned function
.subscribe(...);
Note the map, which is where you pass your id to the returned function. Here you can place whatever parameters you would like.
Hope this helps :)!

How can i check the connection off/on using ionic3

with what i can replace " Network.connection"? it's no more valid !! please i need help
import { Network } from '#ionic-native/network';
isOnline(): boolean {
if(this.onDevice && Network){
return Network.connection!== Connection.NONE;
} else {
return navigator.onLine;
}
}
Check the documentation for the plugin: https://ionicframework.com/docs/native/network/
But in your case it seems to work with
return this.network.type != 'none';
After injecting the plugin of course.

Can I prevent Babel from traversing code inserted by a plugin?

I'm building a plugin that inserts enterFunction() in front of every existing function call by calling path.insertBefore. So my code is transformed from:
myFunction();
To:
enterFunction();
myFunction();
The problem is that when I insert the node Babel once again traverses the inserted node. Here's the logging output:
'CallExpression', 'myFunction'
'CallExpression', 'enterFunction'
How can I prevent Babel from entering the enterFunction call expression and its children?
This is the code I'm currently using for my Babel plugin:
function(babel) {
return {
visitor: {
CallExpression: function(path) {
console.log("CallExpression", path.node.callee.name)
if (path.node.ignore) {
return;
}
path.node.ignore = true
var enterCall = babel.types.callExpression(
babel.types.identifier("enterFunction"), []
)
enterCall.ignore = true;
path.insertBefore(enterCall)
}
}
}
}
The Babel Handbook mentions the following section:
If your plugin needs to not run in a certain situation, the simpliest thing to do is to write an early return.
BinaryExpression(path) {
if (path.node.operator !== '**') return;
}
If you are doing a sub-traversal in a top level path, you can use 2 provided API methods:
path.skip() skips traversing the children of the current path. path.stop() stops traversal entirely.
outerPath.traverse({
Function(innerPath) {
innerPath.skip(); // if checking the children is irrelevant
},
ReferencedIdentifier(innerPath, state) {
state.iife = true;
innerPath.stop(); // if you want to save some state and then stop traversal, or deopt
}
});
In short, use path.skip() to skip traversing the children of the current path.
One application of this method is illustrated in this snippet using Visitors, CallExpression and skip():
export default function (babel) {
const { types: t } = babel;
return {
name: "ast-transform", // not required
visitor: {
CallExpression(path) {
path.replaceWith(t.blockStatement([
t.expressionStatement(t.yieldExpression(path.node))
]));
path.skip();
}
}
};
}