Ecoer Logo

@ipragmatech

45

I love to travel and meeting people with different culture.

steemit.com/@ipragmatech
VOTING POWER100.00%
DOWNVOTE POWER100.00%
RESOURCE CREDITS100.00%
REPUTATION PROGRESS9.59%
Net Worth
1.199USD
STEEM
11.913STEEM
SBD
1.109SBD
Effective Power
5.001SP
├── Own SP
0.125SP
└── Incoming Deleg
+4.876SP

Detailed Balance

STEEM
balance
8.196STEEM
market_balance
0.000STEEM
savings_balance
0.000STEEM
reward_steem_balance
3.717STEEM
STEEM POWER
Own SP
0.125SP
Delegated Out
0.000SP
Delegation In
4.876SP
Effective Power
5.001SP
Reward SP (pending)
5.206SP
SBD
sbd_balance
0.003SBD
sbd_conversions
0.000SBD
sbd_market_balance
0.000SBD
savings_sbd_balance
0.000SBD
reward_sbd_balance
1.106SBD
{
  "balance": "8.196 STEEM",
  "savings_balance": "0.000 STEEM",
  "reward_steem_balance": "3.717 STEEM",
  "vesting_shares": "203.385392 VESTS",
  "delegated_vesting_shares": "0.000000 VESTS",
  "received_vesting_shares": "7940.274414 VESTS",
  "sbd_balance": "0.003 SBD",
  "savings_sbd_balance": "0.000 SBD",
  "reward_sbd_balance": "1.106 SBD",
  "conversions": []
}

Account Info

nameipragmatech
id1020819
rank333,658
reputation170955470172
created2018-05-26T03:39:30
recovery_accountsteem
proxyNone
post_count226
comment_count0
lifetime_vote_count0
witnesses_voted_for0
last_post2019-07-13T06:50:57
last_root_post2019-07-13T06:50:57
last_vote_time2019-07-13T07:06:24
proxied_vsf_votes0, 0, 0, 0
can_vote1
voting_power0
delayed_votes0
balance8.196 STEEM
savings_balance0.000 STEEM
sbd_balance0.003 SBD
savings_sbd_balance0.000 SBD
vesting_shares203.385392 VESTS
delegated_vesting_shares0.000000 VESTS
received_vesting_shares7940.274414 VESTS
reward_vesting_balance10480.079781 VESTS
vesting_balance0.000 STEEM
vesting_withdraw_rate0.000000 VESTS
next_vesting_withdrawal1969-12-31T23:59:59
withdrawn0
to_withdraw0
withdraw_routes0
savings_withdraw_requests0
last_account_recovery1970-01-01T00:00:00
reset_accountnull
last_owner_update1970-01-01T00:00:00
last_account_update2018-08-30T04:58:45
minedNo
sbd_seconds21,324
sbd_last_interest_payment2018-08-18T02:06:39
savings_sbd_last_interest_payment1970-01-01T00:00:00
{
  "active": {
    "account_auths": [],
    "key_auths": [
      [
        "STM6paaq2fsm2uvSkMFtZgcG6JBDwb1wQ7uHVqWecKvUuYH3FpuA7",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "balance": "8.196 STEEM",
  "can_vote": true,
  "comment_count": 0,
  "created": "2018-05-26T03:39:30",
  "curation_rewards": 1,
  "delegated_vesting_shares": "0.000000 VESTS",
  "downvote_manabar": {
    "current_mana": 2035914951,
    "last_update_time": 1779067788
  },
  "guest_bloggers": [],
  "id": 1020819,
  "json_metadata": "{\"profile\":{\"profile_image\":\"https://cdn.steemitimages.com/DQmXG4wKH4Aq7y5Ypimdj7zYdFvqCpvFdeuVWmPoUgzrQgf/IMG_2306.jpg\",\"name\":\"Kapil Jain\",\"about\":\"I love to travel and meeting people with different culture.\",\"location\":\"Delhi, India\",\"website\":\"https://www.ipragmatech.com\",\"cover_image\":\"https://cdn.steemitimages.com/DQmfX8FptYvkJiGCafeg4TXJrp9r9PLsjn3uNyP9ocsDeWs/IMG_20180609_165708452_HDR-EFFECTS.jpg\"}}",
  "last_account_recovery": "1970-01-01T00:00:00",
  "last_account_update": "2018-08-30T04:58:45",
  "last_owner_update": "1970-01-01T00:00:00",
  "last_post": "2019-07-13T06:50:57",
  "last_root_post": "2019-07-13T06:50:57",
  "last_vote_time": "2019-07-13T07:06:24",
  "lifetime_vote_count": 0,
  "market_history": [],
  "memo_key": "STM8VWvWXvi26En5QneqaV5i9ni9m98fP8kNkAXPfhV7qUVhXq3YU",
  "mined": false,
  "name": "ipragmatech",
  "next_vesting_withdrawal": "1969-12-31T23:59:59",
  "other_history": [],
  "owner": {
    "account_auths": [],
    "key_auths": [
      [
        "STM6RxPqEahBSLbSQ81NZtyZBo3tqFmNLWrp9VkXSXSoCmXCa3vqh",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "pending_claimed_accounts": 0,
  "post_bandwidth": 0,
  "post_count": 226,
  "post_history": [],
  "posting": {
    "account_auths": [
      [
        "ipragmatech-app",
        1
      ]
    ],
    "key_auths": [
      [
        "STM6dDD4VUFhTRHWuNhUprcLAf2mhpDJ7Md61DtZetxRihNcrNiy7",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "posting_json_metadata": "{\"profile\":{\"profile_image\":\"https://cdn.steemitimages.com/DQmXG4wKH4Aq7y5Ypimdj7zYdFvqCpvFdeuVWmPoUgzrQgf/IMG_2306.jpg\",\"name\":\"Kapil Jain\",\"about\":\"I love to travel and meeting people with different culture.\",\"location\":\"Delhi, India\",\"website\":\"https://www.ipragmatech.com\",\"cover_image\":\"https://cdn.steemitimages.com/DQmfX8FptYvkJiGCafeg4TXJrp9r9PLsjn3uNyP9ocsDeWs/IMG_20180609_165708452_HDR-EFFECTS.jpg\"}}",
  "posting_rewards": 10399,
  "proxied_vsf_votes": [
    0,
    0,
    0,
    0
  ],
  "proxy": "",
  "received_vesting_shares": "7940.274414 VESTS",
  "recovery_account": "steem",
  "reputation": "170955470172",
  "reset_account": "null",
  "reward_sbd_balance": "1.106 SBD",
  "reward_steem_balance": "3.717 STEEM",
  "reward_vesting_balance": "10480.079781 VESTS",
  "reward_vesting_steem": "5.206 STEEM",
  "savings_balance": "0.000 STEEM",
  "savings_sbd_balance": "0.000 SBD",
  "savings_sbd_last_interest_payment": "1970-01-01T00:00:00",
  "savings_sbd_seconds": "0",
  "savings_sbd_seconds_last_update": "1970-01-01T00:00:00",
  "savings_withdraw_requests": 0,
  "sbd_balance": "0.003 SBD",
  "sbd_last_interest_payment": "2018-08-18T02:06:39",
  "sbd_seconds": "21324",
  "sbd_seconds_last_update": "2018-08-18T05:04:21",
  "tags_usage": [],
  "to_withdraw": 0,
  "transfer_history": [],
  "vesting_balance": "0.000 STEEM",
  "vesting_shares": "203.385392 VESTS",
  "vesting_withdraw_rate": "0.000000 VESTS",
  "vote_history": [],
  "voting_manabar": {
    "current_mana": "8143659806",
    "last_update_time": 1779067788
  },
  "voting_power": 0,
  "withdraw_routes": 0,
  "withdrawn": 0,
  "witness_votes": [],
  "witnesses_voted_for": 0,
  "rank": 333658
}

Withdraw Routes

IncomingOutgoing
Empty
Empty
{
  "incoming": [],
  "outgoing": []
}
From Date
To Date
steemdelegated 4.876 SP to @ipragmatech
2026/05/18 01:29:48
delegateeipragmatech
delegatorsteem
vesting shares7940.274414 VESTS
Transaction InfoBlock #106144931/Trx 238d09e4af71fdcbd44f69bd114063e6af32593a
View Raw JSON Data
{
  "block": 106144931,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "7940.274414 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-05-18T01:29:48",
  "trx_id": "238d09e4af71fdcbd44f69bd114063e6af32593a",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 3.211 SP to @ipragmatech
2026/05/12 08:53:30
delegateeipragmatech
delegatorsteem
vesting shares5228.064009 VESTS
Transaction InfoBlock #105981760/Trx 1a4d36ecc8151fefe3455d283bdaf489c59d8c20
View Raw JSON Data
{
  "block": 105981760,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "5228.064009 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-05-12T08:53:30",
  "trx_id": "1a4d36ecc8151fefe3455d283bdaf489c59d8c20",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 4.884 SP to @ipragmatech
2026/04/26 00:48:42
delegateeipragmatech
delegatorsteem
vesting shares7952.790170 VESTS
Transaction InfoBlock #105512550/Trx 00ef196b145e1a3dd2fc98b87c1f77ca1754422c
View Raw JSON Data
{
  "block": 105512550,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "7952.790170 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-04-26T00:48:42",
  "trx_id": "00ef196b145e1a3dd2fc98b87c1f77ca1754422c",
  "trx_in_block": 1,
  "virtual_op": 0
}
steemdelegated 3.236 SP to @ipragmatech
2026/01/23 11:08:54
delegateeipragmatech
delegatorsteem
vesting shares5269.610828 VESTS
Transaction InfoBlock #102855823/Trx 1cb34d3b0b8014b7f8a40311af207641562618fe
View Raw JSON Data
{
  "block": 102855823,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "5269.610828 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-01-23T11:08:54",
  "trx_id": "1cb34d3b0b8014b7f8a40311af207641562618fe",
  "trx_in_block": 2,
  "virtual_op": 0
}
2025/04/19 07:17:57
authorphernandez41
bodyCash payment gateways offer a simple solution for sellers who prefer offline transactions. These systems are especially useful in regions with low credit card usage. For sellers facing issues with missed micro-payments, learning <a href="https://myothello.net/">소액결제 미납 뚫는법</a> (how to bypass missed small payments) becomes crucial. By understanding this method, sellers can secure their earnings and reduce financial risks. Implementing reliable cash gateway systems enhances trust, ensures smoother transactions, and improves customer satisfaction through accessible payment options.
json metadata{"links":["https://myothello.net/"],"app":"steemit/0.2"}
parent authoripragmatech
parent permlinktopsixsocialenginepaymentgateway-g2u9zdglfv
permlinksuyexw
title
Transaction InfoBlock #94835841/Trx 36985804919738a5567b1b58a216cf63f6b9100b
View Raw JSON Data
{
  "block": 94835841,
  "op": [
    "comment",
    {
      "author": "phernandez41",
      "body": "Cash payment gateways offer a simple solution for sellers who prefer offline transactions. These systems are especially useful in regions with low credit card usage. For sellers facing issues with missed micro-payments, learning <a href=\"https://myothello.net/\">소액결제 미납 뚫는법</a> (how to bypass missed small payments) becomes crucial. By understanding this method, sellers can secure their earnings and reduce financial risks. Implementing reliable cash gateway systems enhances trust, ensures smoother transactions, and improves customer satisfaction through accessible payment options.",
      "json_metadata": "{\"links\":[\"https://myothello.net/\"],\"app\":\"steemit/0.2\"}",
      "parent_author": "ipragmatech",
      "parent_permlink": "topsixsocialenginepaymentgateway-g2u9zdglfv",
      "permlink": "suyexw",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2025-04-19T07:17:57",
  "trx_id": "36985804919738a5567b1b58a216cf63f6b9100b",
  "trx_in_block": 7,
  "virtual_op": 0
}
steemdelegated 3.337 SP to @ipragmatech
2024/12/17 06:26:03
delegateeipragmatech
delegatorsteem
vesting shares5433.830025 VESTS
Transaction InfoBlock #91302181/Trx e88a65571e5c469a0a07f63d6919fe1abd3f0702
View Raw JSON Data
{
  "block": 91302181,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "5433.830025 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2024-12-17T06:26:03",
  "trx_id": "e88a65571e5c469a0a07f63d6919fe1abd3f0702",
  "trx_in_block": 0,
  "virtual_op": 0
}
2024/02/12 10:40:45
authorbilanio
bodyLook, you're right, because there's no need for ongoing developer services right now. The good thing about Magento is that there are a lot of ready-made extensions that are quickly and easily integrated into the platform. As for me, I prefer to work with Amasty specialists, and their latest extension that I installed is <a href="https://amasty.com/social-login-for-magento-2.html">magento 2 social login extension</a>. For me, this is a way to attract more new clients through social networks and make my service more convenient for buyers.
json metadata{"links":["https://amasty.com/social-login-for-magento-2.html"],"app":"steemit/0.2"}
parent authoripragmatech
parent permlinkhowtobuildcustommagentorestapieffortlesslyinlessthan2hourspart1-aiulfonaae
permlinks8qobp
title
Transaction InfoBlock #82446917/Trx ce918e2e9f999bf53a32ff818853fdc840b1279a
View Raw JSON Data
{
  "block": 82446917,
  "op": [
    "comment",
    {
      "author": "bilanio",
      "body": "Look, you're right, because there's no need for ongoing developer services right now. The good thing about Magento is that there are a lot of ready-made extensions that are quickly and easily integrated into the platform. As for me, I prefer to work with Amasty specialists, and their latest extension that I installed is <a href=\"https://amasty.com/social-login-for-magento-2.html\">magento 2 social login extension</a>. For me, this is a way to attract more new clients through social networks and make my service more convenient for buyers.",
      "json_metadata": "{\"links\":[\"https://amasty.com/social-login-for-magento-2.html\"],\"app\":\"steemit/0.2\"}",
      "parent_author": "ipragmatech",
      "parent_permlink": "howtobuildcustommagentorestapieffortlesslyinlessthan2hourspart1-aiulfonaae",
      "permlink": "s8qobp",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2024-02-12T10:40:45",
  "trx_id": "ce918e2e9f999bf53a32ff818853fdc840b1279a",
  "trx_in_block": 6,
  "virtual_op": 0
}
2024/02/12 10:39:48
authormilaniask
bodyIf I work on Magento, do I have to contact the developers every time to add something new to the platform? It seems to me that there must be simpler solutions.
json metadata{"app":"steemit/0.2"}
parent authoripragmatech
parent permlinkhowtobuildcustommagentorestapieffortlesslyinlessthan2hourspart1-aiulfonaae
permlinks8qoac
title
Transaction InfoBlock #82446899/Trx 498eb42e90ae6a7d6e00dd0e80df935babe7eee7
View Raw JSON Data
{
  "block": 82446899,
  "op": [
    "comment",
    {
      "author": "milaniask",
      "body": "If I work on Magento, do I have to contact the developers every time to add something new to the platform? It seems to me that there must be simpler solutions.",
      "json_metadata": "{\"app\":\"steemit/0.2\"}",
      "parent_author": "ipragmatech",
      "parent_permlink": "howtobuildcustommagentorestapieffortlesslyinlessthan2hourspart1-aiulfonaae",
      "permlink": "s8qoac",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2024-02-12T10:39:48",
  "trx_id": "498eb42e90ae6a7d6e00dd0e80df935babe7eee7",
  "trx_in_block": 6,
  "virtual_op": 0
}
steemdelegated 3.441 SP to @ipragmatech
2023/11/13 22:08:00
delegateeipragmatech
delegatorsteem
vesting shares5602.963557 VESTS
Transaction InfoBlock #79856365/Trx 84981939b95f5850221f72ce6682fcea9f9b1af7
View Raw JSON Data
{
  "block": 79856365,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "5602.963557 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2023-11-13T22:08:00",
  "trx_id": "84981939b95f5850221f72ce6682fcea9f9b1af7",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 5.245 SP to @ipragmatech
2023/09/21 23:18:03
delegateeipragmatech
delegatorsteem
vesting shares8540.242343 VESTS
Transaction InfoBlock #78349590/Trx a23f583f65665a21325a539ae56815e6823edc4c
View Raw JSON Data
{
  "block": 78349590,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "8540.242343 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2023-09-21T23:18:03",
  "trx_id": "a23f583f65665a21325a539ae56815e6823edc4c",
  "trx_in_block": 2,
  "virtual_op": 0
}
2023/03/15 13:42:30
authoryana-kl
body@@ -247,16 +247,57 @@ usiness. + Here is information about the process of %3Ca href @@ -384,53 +384,8 @@ p/%22%3E -Here%3C/a%3E is information about the process of crea @@ -405,12 +405,16 @@ application. +%3C/a%3E
json metadata{"links":["https://www.cleveroad.com/blog/practical-tutorial-on-how-to-make-a-shopping-app/"],"app":"steemit/0.2"}
parent authoripragmatech
parent permlinkacompleteguidetobuildanativee-commercemobileapp-hlzqngjpub
permlinkrh0fmz
title
Transaction InfoBlock #72896334/Trx d7dc95ae2447bea1f8d88670a69753b6a6581f0a
View Raw JSON Data
{
  "block": 72896334,
  "op": [
    "comment",
    {
      "author": "yana-kl",
      "body": "@@ -247,16 +247,57 @@\n usiness.\n+ Here is information about the process of\n  %3Ca href\n@@ -384,53 +384,8 @@\n p/%22%3E\n-Here%3C/a%3E is information about the process of \n crea\n@@ -405,12 +405,16 @@\n application.\n+%3C/a%3E\n",
      "json_metadata": "{\"links\":[\"https://www.cleveroad.com/blog/practical-tutorial-on-how-to-make-a-shopping-app/\"],\"app\":\"steemit/0.2\"}",
      "parent_author": "ipragmatech",
      "parent_permlink": "acompleteguidetobuildanativee-commercemobileapp-hlzqngjpub",
      "permlink": "rh0fmz",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2023-03-15T13:42:30",
  "trx_id": "d7dc95ae2447bea1f8d88670a69753b6a6581f0a",
  "trx_in_block": 4,
  "virtual_op": 0
}
steemdelegated 5.381 SP to @ipragmatech
2022/11/03 12:54:00
delegateeipragmatech
delegatorsteem
vesting shares8761.923781 VESTS
Transaction InfoBlock #69114690/Trx 503f5187d2065948cf8bf2caf3b4dfd9fd1c8932
View Raw JSON Data
{
  "block": 69114690,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "8761.923781 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2022-11-03T12:54:00",
  "trx_id": "503f5187d2065948cf8bf2caf3b4dfd9fd1c8932",
  "trx_in_block": 2,
  "virtual_op": 0
}
2022/08/22 09:28:18
authoryana-kl
bodyThanks for sharing such useful information. Today's consumer habits have given rise to on-the-go shopping, and the mobile experience has become more important than ever. This is the main reason why you should create an online store app for your business. <a href="https://www.cleveroad.com/blog/practical-tutorial-on-how-to-make-a-shopping-app/">Here</a> is information about the process of creating a store application.
json metadata{"links":["https://www.cleveroad.com/blog/practical-tutorial-on-how-to-make-a-shopping-app/"],"app":"steemit/0.2"}
parent authoripragmatech
parent permlinkacompleteguidetobuildanativee-commercemobileapp-hlzqngjpub
permlinkrh0fmz
title
Transaction InfoBlock #67021285/Trx ffa4ce528b0295bd50e680f4b4372aec4db7a1ca
View Raw JSON Data
{
  "block": 67021285,
  "op": [
    "comment",
    {
      "author": "yana-kl",
      "body": "Thanks for sharing such useful information. Today's consumer habits have given rise to on-the-go shopping, and the mobile experience has become more important than ever. This is the main reason why you should create an online store app for your business. <a href=\"https://www.cleveroad.com/blog/practical-tutorial-on-how-to-make-a-shopping-app/\">Here</a> is information about the process of creating a store application.",
      "json_metadata": "{\"links\":[\"https://www.cleveroad.com/blog/practical-tutorial-on-how-to-make-a-shopping-app/\"],\"app\":\"steemit/0.2\"}",
      "parent_author": "ipragmatech",
      "parent_permlink": "acompleteguidetobuildanativee-commercemobileapp-hlzqngjpub",
      "permlink": "rh0fmz",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2022-08-22T09:28:18",
  "trx_id": "ffa4ce528b0295bd50e680f4b4372aec4db7a1ca",
  "trx_in_block": 6,
  "virtual_op": 0
}
trx-steemsent 0.001 STEEM to @ipragmatech- "Hello ipragmatech, I automate the swapping between trx back to Steem. Just send 15 or more trx to >>> TUep3qrvP4QwqHtoXJjdQ6Q7JRQdyuaJQH | put your Steem username no @ for the memo <<< You will r..."
2022/08/09 20:28:06
amount0.001 STEEM
fromtrx-steem
memoHello ipragmatech, I automate the swapping between trx back to Steem. Just send 15 or more trx to >>> TUep3qrvP4QwqHtoXJjdQ6Q7JRQdyuaJQH | put your Steem username no @ for the memo <<< You will recieve the market value of tron converted to steem. within seconds. I posted a my results from sending it 100 tron yesterday here -> https://steemit.com/trx/@steemegg/sending-100-trx-to-trx-steem-and-i-got-back-25-203-in-6-seconds
toipragmatech
Transaction InfoBlock #66662441/Trx 6305403656344636d4c10146e5f17cd9a5045fb4
View Raw JSON Data
{
  "block": 66662441,
  "op": [
    "transfer",
    {
      "amount": "0.001 STEEM",
      "from": "trx-steem",
      "memo": "Hello ipragmatech, I automate the swapping between trx back to Steem.  Just send 15 or more trx to >>>   TUep3qrvP4QwqHtoXJjdQ6Q7JRQdyuaJQH   | put your Steem username no @ for the memo <<< You will recieve the market value of tron converted to steem. within seconds.  I posted a my results from sending it 100 tron yesterday here ->  https://steemit.com/trx/@steemegg/sending-100-trx-to-trx-steem-and-i-got-back-25-203-in-6-seconds",
      "to": "ipragmatech"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2022-08-09T20:28:06",
  "trx_id": "6305403656344636d4c10146e5f17cd9a5045fb4",
  "trx_in_block": 31,
  "virtual_op": 0
}
steemdelegated 5.516 SP to @ipragmatech
2022/01/17 12:03:57
delegateeipragmatech
delegatorsteem
vesting shares8982.457012 VESTS
Transaction InfoBlock #60810740/Trx 264c7d38ee5a340fcbc7f4cfc9b9cb4208cf65fd
View Raw JSON Data
{
  "block": 60810740,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "8982.457012 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2022-01-17T12:03:57",
  "trx_id": "264c7d38ee5a340fcbc7f4cfc9b9cb4208cf65fd",
  "trx_in_block": 4,
  "virtual_op": 0
}
steemdelegated 5.629 SP to @ipragmatech
2021/06/14 01:56:12
delegateeipragmatech
delegatorsteem
vesting shares9166.225670 VESTS
Transaction InfoBlock #54609061/Trx 0080d12d263d92ded47054b9756ec97b2e793165
View Raw JSON Data
{
  "block": 54609061,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "9166.225670 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2021-06-14T01:56:12",
  "trx_id": "0080d12d263d92ded47054b9756ec97b2e793165",
  "trx_in_block": 2,
  "virtual_op": 0
}
steemdelegated 5.744 SP to @ipragmatech
2020/12/11 12:13:15
delegateeipragmatech
delegatorsteem
vesting shares9353.647644 VESTS
Transaction InfoBlock #49356470/Trx ea18591a9c4b8768aadfc30221e58a090269f036
View Raw JSON Data
{
  "block": 49356470,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "9353.647644 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-11T12:13:15",
  "trx_id": "ea18591a9c4b8768aadfc30221e58a090269f036",
  "trx_in_block": 3,
  "virtual_op": 0
}
steemdelegated 1.175 SP to @ipragmatech
2020/12/06 05:50:15
delegateeipragmatech
delegatorsteem
vesting shares1912.543513 VESTS
Transaction InfoBlock #49208029/Trx 1ef50b4521ddd5b8465ced55480c029a1a8c486f
View Raw JSON Data
{
  "block": 49208029,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "1912.543513 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-06T05:50:15",
  "trx_id": "1ef50b4521ddd5b8465ced55480c029a1a8c486f",
  "trx_in_block": 5,
  "virtual_op": 0
}
steemdelegated 5.748 SP to @ipragmatech
2020/12/05 15:51:09
delegateeipragmatech
delegatorsteem
vesting shares9359.855498 VESTS
Transaction InfoBlock #49191564/Trx 2ed8afa41c4beb8e361525d3c2c3296de04fb5a9
View Raw JSON Data
{
  "block": 49191564,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "9359.855498 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-05T15:51:09",
  "trx_id": "2ed8afa41c4beb8e361525d3c2c3296de04fb5a9",
  "trx_in_block": 7,
  "virtual_op": 0
}
steemdelegated 1.179 SP to @ipragmatech
2020/11/02 17:55:54
delegateeipragmatech
delegatorsteem
vesting shares1920.017158 VESTS
Transaction InfoBlock #48260503/Trx 6828985cff67dce77a7dfdd747b9b195cca999cb
View Raw JSON Data
{
  "block": 48260503,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "1920.017158 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-11-02T17:55:54",
  "trx_id": "6828985cff67dce77a7dfdd747b9b195cca999cb",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 5.873 SP to @ipragmatech
2020/05/09 06:48:42
delegateeipragmatech
delegatorsteem
vesting shares9562.660857 VESTS
Transaction InfoBlock #43218295/Trx 8e2e90577d7f7bcb70db70623e288caf33945daa
View Raw JSON Data
{
  "block": 43218295,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "9562.660857 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-05-09T06:48:42",
  "trx_id": "8e2e90577d7f7bcb70db70623e288caf33945daa",
  "trx_in_block": 8,
  "virtual_op": 0
}
steemdelegated 1.200 SP to @ipragmatech
2020/05/08 10:34:42
delegateeipragmatech
delegatorsteem
vesting shares1953.311140 VESTS
Transaction InfoBlock #43194583/Trx 918dae01b52bf832e2ae6b42f93253d9e8bf8ca2
View Raw JSON Data
{
  "block": 43194583,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "1953.311140 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-05-08T10:34:42",
  "trx_id": "918dae01b52bf832e2ae6b42f93253d9e8bf8ca2",
  "trx_in_block": 14,
  "virtual_op": 0
}
2020/02/07 12:52:06
authorsteemitboard
bodyCongratulations @ipragmatech! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) : <table><tr><td><img src="https://steemitimages.com/60x70/http://steemitboard.com/@ipragmatech/payout.png?202002071227"></td><td>You received more than 10 as payout for your posts. Your next target is to reach a total payout of 50</td></tr> </table> <sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@ipragmatech) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=ipragmatech)_</sub> <sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub> **Do not miss the last post from @steemitboard:** <table><tr><td><a href="https://steemit.com/steemitboard/@steemitboard/steemitboard-ranking-update-a-better-rich-list-comparator"><img src="https://steemitimages.com/64x128/https://cdn.steemitimages.com/DQmfRVpHQhLDhnjDtqck8GPv9NPvNKPfMsDaAFDE1D9Er2Z/header_ranking.png"></a></td><td><a href="https://steemit.com/steemitboard/@steemitboard/steemitboard-ranking-update-a-better-rich-list-comparator">SteemitBoard Ranking update - A better rich list comparator</a></td></tr></table> ###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
parent authoripragmatech
parent permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
permlinksteemitboard-notify-ipragmatech-20200207t125205000z
title
Transaction InfoBlock #40611221/Trx 2af74f310a34101bb94786633ea692029fc7c536
View Raw JSON Data
{
  "block": 40611221,
  "op": [
    "comment",
    {
      "author": "steemitboard",
      "body": "Congratulations @ipragmatech! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :\n\n<table><tr><td><img src=\"https://steemitimages.com/60x70/http://steemitboard.com/@ipragmatech/payout.png?202002071227\"></td><td>You received more than 10 as payout for your posts. Your next target is to reach a total payout of 50</td></tr>\n</table>\n\n<sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@ipragmatech) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=ipragmatech)_</sub>\n<sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub>\n\n\n\n**Do not miss the last post from @steemitboard:**\n<table><tr><td><a href=\"https://steemit.com/steemitboard/@steemitboard/steemitboard-ranking-update-a-better-rich-list-comparator\"><img src=\"https://steemitimages.com/64x128/https://cdn.steemitimages.com/DQmfRVpHQhLDhnjDtqck8GPv9NPvNKPfMsDaAFDE1D9Er2Z/header_ranking.png\"></a></td><td><a href=\"https://steemit.com/steemitboard/@steemitboard/steemitboard-ranking-update-a-better-rich-list-comparator\">SteemitBoard Ranking update - A better rich list comparator</a></td></tr></table>\n\n###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}",
      "parent_author": "ipragmatech",
      "parent_permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag",
      "permlink": "steemitboard-notify-ipragmatech-20200207t125205000z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-02-07T12:52:06",
  "trx_id": "2af74f310a34101bb94786633ea692029fc7c536",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 5.945 SP to @ipragmatech
2019/10/12 08:39:57
delegateeipragmatech
delegatorsteem
vesting shares9680.845165 VESTS
Transaction InfoBlock #37214327/Trx 9cde3a8823612865bae2c3b129e2845fe311e03b
View Raw JSON Data
{
  "block": 37214327,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "9680.845165 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-10-12T08:39:57",
  "trx_id": "9cde3a8823612865bae2c3b129e2845fe311e03b",
  "trx_in_block": 6,
  "virtual_op": 0
}
2019/07/20 06:50:57
authoripragmatech
permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
sbd payout0.000 SBD
steem payout0.474 STEEM
vesting payout951.754995 VESTS
Transaction InfoBlock #34820650/Virtual Operation #6
View Raw JSON Data
{
  "block": 34820650,
  "op": [
    "author_reward",
    {
      "author": "ipragmatech",
      "permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.474 STEEM",
      "vesting_payout": "951.754995 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-20T06:50:57",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 6
}
steempressreceived 0.102 SP benefactor reward from @ipragmatech
2019/07/20 06:50:57
authoripragmatech
benefactorsteempress
permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
sbd payout0.000 SBD
steem payout0.084 STEEM
vesting payout166.904842 VESTS
Transaction InfoBlock #34820650/Virtual Operation #5
View Raw JSON Data
{
  "block": 34820650,
  "op": [
    "comment_benefactor_reward",
    {
      "author": "ipragmatech",
      "benefactor": "steempress",
      "permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.084 STEEM",
      "vesting_payout": "166.904842 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-20T06:50:57",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 5
}
2019/07/20 06:50:57
comment authoripragmatech
comment permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
curatoripragmatech
reward1.986962 VESTS
Transaction InfoBlock #34820650/Virtual Operation #4
View Raw JSON Data
{
  "block": 34820650,
  "op": [
    "curation_reward",
    {
      "comment_author": "ipragmatech",
      "comment_permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag",
      "curator": "ipragmatech",
      "reward": "1.986962 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-20T06:50:57",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 4
}
steemdelegated 18.186 SP to @ipragmatech
2019/07/13 08:52:30
delegateeipragmatech
delegatorsteem
vesting shares29612.790926 VESTS
Transaction InfoBlock #34621720/Trx c0a7c25dc9c49d6346a5e259cd242fe82dd5b60a
View Raw JSON Data
{
  "block": 34621720,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "29612.790926 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-13T08:52:30",
  "trx_id": "c0a7c25dc9c49d6346a5e259cd242fe82dd5b60a",
  "trx_in_block": 16,
  "virtual_op": 0
}
2019/07/13 07:17:48
authoripragmatech
permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
voterberien
weight250 (2.50%)
Transaction InfoBlock #34619828/Trx 62904a8ab3e9771972b0ec54b049241a456fb678
View Raw JSON Data
{
  "block": 34619828,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag",
      "voter": "berien",
      "weight": 250
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-13T07:17:48",
  "trx_id": "62904a8ab3e9771972b0ec54b049241a456fb678",
  "trx_in_block": 14,
  "virtual_op": 0
}
2019/07/13 07:17:42
authoripragmatech
permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
votersteempress-io
weight250 (2.50%)
Transaction InfoBlock #34619826/Trx 4c323269275d65e0dd04466b3d2c9fa9b171fc28
View Raw JSON Data
{
  "block": 34619826,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag",
      "voter": "steempress-io",
      "weight": 250
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-13T07:17:42",
  "trx_id": "4c323269275d65e0dd04466b3d2c9fa9b171fc28",
  "trx_in_block": 1,
  "virtual_op": 0
}
2019/07/13 07:17:33
authoripragmatech
permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
votersteempress
weight250 (2.50%)
Transaction InfoBlock #34619823/Trx 066d16440352f5b0f454cc555c0806c43b04e28b
View Raw JSON Data
{
  "block": 34619823,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag",
      "voter": "steempress",
      "weight": 250
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-13T07:17:33",
  "trx_id": "066d16440352f5b0f454cc555c0806c43b04e28b",
  "trx_in_block": 24,
  "virtual_op": 0
}
2019/07/13 07:06:24
authoripragmatech
permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
voteripragmatech
weight10000 (100.00%)
Transaction InfoBlock #34619600/Trx b54df42183b309405744051d52ef8a707c7a9010
View Raw JSON Data
{
  "block": 34619600,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag",
      "voter": "ipragmatech",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-13T07:06:24",
  "trx_id": "b54df42183b309405744051d52ef8a707c7a9010",
  "trx_in_block": 5,
  "virtual_op": 0
}
2019/07/13 06:55:39
authoripragmatech
permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
votersteeming-hot
weight1 (0.01%)
Transaction InfoBlock #34619385/Trx 4c787a764af04e1474e095f36f4edaa14eab5afd
View Raw JSON Data
{
  "block": 34619385,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag",
      "voter": "steeming-hot",
      "weight": 1
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-13T06:55:39",
  "trx_id": "4c787a764af04e1474e095f36f4edaa14eab5afd",
  "trx_in_block": 17,
  "virtual_op": 0
}
2019/07/13 06:53:48
authoripragmatech
permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
voterfityan
weight10000 (100.00%)
Transaction InfoBlock #34619348/Trx 465625de20d83f295ffad3ebbe429907eadaa09a
View Raw JSON Data
{
  "block": 34619348,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag",
      "voter": "fityan",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-13T06:53:48",
  "trx_id": "465625de20d83f295ffad3ebbe429907eadaa09a",
  "trx_in_block": 21,
  "virtual_op": 0
}
2019/07/13 06:50:57
allow curation rewardstrue
allow votestrue
authoripragmatech
extensions[[0,{"beneficiaries":[{"account":"steempress","weight":1500}]}]]
max accepted payout1000000.000 SBD
percent steem dollars10000
permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
Transaction InfoBlock #34619291/Trx 5598cedaf4f54cc70e913f375c26d83c1acef5b3
View Raw JSON Data
{
  "block": 34619291,
  "op": [
    "comment_options",
    {
      "allow_curation_rewards": true,
      "allow_votes": true,
      "author": "ipragmatech",
      "extensions": [
        [
          0,
          {
            "beneficiaries": [
              {
                "account": "steempress",
                "weight": 1500
              }
            ]
          }
        ]
      ],
      "max_accepted_payout": "1000000.000 SBD",
      "percent_steem_dollars": 10000,
      "permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-13T06:50:57",
  "trx_id": "5598cedaf4f54cc70e913f375c26d83c1acef5b3",
  "trx_in_block": 0,
  "virtual_op": 0
}
2019/07/13 06:50:57
authoripragmatech
body<center>http://www.ipragmatech.com/wp-content/uploads/2019/07/react-e-commerce.png</center> <br/>There are also a few frontend platforms into which you can integrate e-commerce functionalities, like <a href="https://snipcart.com/blog/react-seo-nextjs-tutorial">Next.js</a>, a lightweight framework for static and server-rendered apps. Finally, we’ve chosen for this post? React E-commerce Builder. We’ll integrate it with our shopping cart for developers. The result <strong>should</strong> be a neat, React-powered e-commerce app! <h2>Why Should you use React for e-commerce?</h2> A common E-commerce website usually comprises a plethora of forms to fill, complex filters, elements, which interact with different APIs, maps, etc. With the help of React, you can easily implement all of those features, making it a good option to build highly interactive E-commerce websites. One of the great things about React is that it allows for a rather convenient way of storing and manipulating the state of your app (e.g. filtering through items is a change in the state of the app). What’s more, React comes with a whole bunch of ready-made modules for all occasions, not mentioning that it’s easy to test and scale. It has been at the forefront of frontend web development for a few years now. It boasts a constellation of stars at the top of its GitHub repo. It’s used by tech behemoths like Airbnb, Netflix, and Instagram. It was created by Facebook developers for Pete’s sake! Saying it’s trendy is an understatement. React has proven its awesomeness more than enough. With its component-centric development, Virtual DOM, JSX syntax, etc. it has changed frontend development for the best. <h3>Features:</h3> <ul> <li> <h4><strong>The use of components for flexibility: </strong></h4> Component-based development enables easy code reuse through your app, but also the writing of small features. Or, in our case, small e-commerce functionalities. This comes in handy once you start scaling and expanding your shopping cart integration. I’ll show you a concrete example in the demo further down.</li> </ul> <ul> <li> <h4><strong>Virtual DOM for performance: </strong></h4> React’s <a class="external-link" href="https://www.rigelnetworks.com/using-virtual-dom-react-js-top-5-benefits/" target="_blank" rel="noopener">virtual DOM</a> provides a more efficient way of updating the view in a web application. Performance is HUGE in e-commerce; every milli-seconds count. Speed = Better UX/SEO = $$$.</li> </ul> <ul> <li> <h4><strong>Popularity &amp; vast community for peace of mind: </strong></h4> If you’re a merchant, it shouldn’t be too hard finding developers to maintain your React e-commerce app. If you’re a developer, any issue has probably already been documented. Also, the ecosystem has spawned dozens of excellent dev tools to optimize React development.</li> <li> <h4><strong><strong>Have a look at React e-commer</strong>ce tools: </strong></h4> A couple of solutions will let you kickstart your e-commerce development with React: <ul> <li><a class="external-link" href="https://moltin.com/react-js/" target="_blank" rel="noopener"><strong>Moltin</strong></a> <strong>-</strong> An API-based e-commerce solution. It allows you to use React natively to power your applications.</li> <li><a class="external-link" href="https://cezerin.com/" target="_blank" rel="noopener"><strong>Cezerin</strong></a> <strong>-</strong> A React &amp; Node.js-based e-commerce platform. Enables the creation of PWAs.</li> <li><a class="external-link" href="https://www.reactioncommerce.com/" target="_blank" rel="noopener"><strong>Reaction Commerce</strong></a> <strong>-</strong> Open-source, real-time platform. Built on Node.js, but plays nice with React.</li> </ul> </li> </ul> React E-commerce Builder is a React and Node.js based eCommerce platform. The project has two components i.e. <a href="https://github.com/ipragmatechadmin/React-Ecommerce-Builder/tree/master/client" target="_blank" rel="noopener">client (react)</a> and <a href="https://github.com/ipragmatechadmin/React-Ecommerce-Builder/tree/master/server" target="_blank" rel="noopener">server-side (node.js)</a>. Please download or clone the respective components and follow the instructions for the setup. <h2>Client:</h2> The React E-commerce is a project relying on [<a href="https://facebook.github.io/react/docs/hello-world.html" target="_blank" rel="noopener">React]</a> a powerful javascript library for building the user interface. In this project, I tried to show some features of react/react components as an e-commerce platform. The structure of this project gives the ability to the developer to develop their project on their own idea and environment. <h3>Features:</h3> <ul> <li>Product listing</li> <li><center><img class="aligncenter wp-image-26114 size-full" src="http://www.ipragmatech.com/wp-content/uploads/2019/07/ProductList.png" alt="" width="825" height="777" /></center><br/></li> <li>Search the product by text</li> <li>Product Details</li> <li>SignIn and Signup</li> <li>Add to cart</li> <li>Payment through PayPal</li> <li>Update Shipping Details</li> </ul> <h3>Structure:</h3> The current structure could make the project easy to change and scale up. Using the current structure we are able to develop the mobile app in parallel with web app <strong>only</strong> with changing <code>Components</code> layer. It means we can keep <code>Core</code>, <code>Data</code> layers, <code>Actions</code>, <code>Reducers</code>, etc. What we have high reusability and fast in producing the products. So here is the structure of the project: These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system. <h3><a id="user-content-prerequisites" class="anchor" href="https://github.com/ipragmatechadmin/React-Ecommerce-Builder/tree/master/client#prerequisites" aria-hidden="true"></a>Prerequisites</h3> Install <a href="https://nodejs.org/en/" target="_blank" rel="nofollow noopener">NodeJs</a> <h4><a id="user-content-note" class="anchor" href="https://github.com/ipragmatechadmin/React-Ecommerce-Builder/tree/master/client#note" aria-hidden="true"></a>Note</h4> <ul> <li>If you're using Windows you should install all node-gyp dependencies with following commands:</li> <li><script src="https://gist.github.com/Abhiranjanchaurasia/1b95ed6c3d28c484a08078aefe80e15f.js"></script></li> <li>and then install the package</li> <li><script src="https://gist.github.com/Abhiranjanchaurasia/7097aadbbf7c01538c07b6ec86754c52.js"></script></li> </ul> <h3><a id="user-content-installing" class="anchor" href="https://github.com/ipragmatechadmin/React-Ecommerce-Builder/tree/master/client#installing" aria-hidden="true"></a>Installing</h3> <ul> <li>Download the source code file or clone it from <a href="https://github.com/ipragmatechadmin/React-Ecommerce-Builder" target="_blank" rel="noopener">https://github.com/ipragmatechadmin/React-Ecommerce-Builder.</a></li> <li>Go to the project root directory</li> <li><script src="https://gist.github.com/Abhiranjanchaurasia/b71859fb33648cbf5fbcecb5a3830056.js"></script></li> <li>To install node dependencies use</li> <li><script src="https://gist.github.com/Abhiranjanchaurasia/c5d9c21be1ad461a0358d668e13e2e06.js"></script></li> <li>Open environment config and set the APIs URL. React E-commerce is able to be connected with current Node Web APIs.</li> <li>Once done we are ready to use the e-commerce app. <script src="https://gist.github.com/Abhiranjanchaurasia/34f8c71bb10d272cd4c87af209cd76fb.js"></script></li> </ul> [av_hr class='short' height='50' shadow='no-shadow' position='center' custom_border='av-border-thin' custom_width='50px' custom_border_color='' custom_margin_top='30px' custom_margin_bottom='30px' icon_select='yes' custom_icon_color='' icon='ue808' font='entypo-fontello' av_uid='av-3bdd715' custom_class='' admin_preview_bg=''] <h2>Server:</h2> An eCommerce platform for Node web APIs focused on the separation of concerns and scalability. The app is deployed on Heroku and APIs documentation is available at <a href="https://ipragmatech-ecommmerce.herokuapp.com/api/docs" target="_blank" rel="nofollow noopener">https://ipragmatech-ecommmerce.herokuapp.com/api/docs</a> <h3>Quick Start:</h3> This platform has basic web APIs for the e-commerce app. The platform uses backend as a MySQL database but can be used for other platforms like firebase, dynamodb, etc. <ul> <li>Download the source code file or clone it from <a href="https://github.com/ipragmatechadmin/React-Ecommerce-Builder" target="_blank" rel="noopener">https://github.com/ipragmatechadmin/React-Ecommerce-Builder</a>.</li> <li>Setup the database on <code>config/database.js</code> with the MySQL database configurations.</li> <li>Go to the root directory  server</li> <li><script src="https://gist.github.com/Abhiranjanchaurasia/726a7feed5b57457a525f705515d4e44.js"></script></li> <li>Install the dependencies with <code>yarn</code> or npm (click here if <a href="https://yarnpkg.com/docs/install" target="_blank" rel="nofollow noopener">you don't have Yarn installed</a>)</li> <li><script src="https://gist.github.com/Abhiranjanchaurasia/c5d9c21be1ad461a0358d668e13e2e06.js"></script></li> <li>Create the development and test databases you have set up on <code>config/database.js</code>:</li> <li><script src="https://gist.github.com/Abhiranjanchaurasia/9bb2d7d8f180bbad2da953ec4f12d05b.js"></script></li> <li>Run the database script located at <code>src/infra/database scripts</code>. This shall create the sample data along with tables and stored procedures.</li> <li>If MySQL is not present with the local system, download the MYSQL to the system.</li> <li>Start the MYSQL Server and import the database tables like:</li> <li><script src="https://gist.github.com/Abhiranjanchaurasia/2292c911a6e5b65ca0faa8b59a65026b.js"></script></li> <li>For Database backup, there is a need to export the database like:</li> <li><script src="https://gist.github.com/Abhiranjanchaurasia/b75dd19395d82c679ba0b7079f7368e0.js"></script></li> <li>Run the application in development mode with <code>npm run dev</code></li> <li>Access <code>http://localhost:3000/api/docs</code> and you can check the APIs documentation. You can test the APIs by changing the base URL. you're ready to go!</li> </ul> <h3>Script:</h3> This boilerplate comes with a collection of npm scripts to make your life easier, you'll run them with <code>npm run &lt;script name&gt;</code> or <code>yarn run &lt;script name&gt;</code>: <ul> <li><strong><code>dev</code></strong>: Run the application in development mode</li> <li><strong><code>start</code></strong> Run the application in production mode (prefer not to do that in development)</li> <li><strong><code>test</code></strong>: Run the test suite</li> <li><strong><code>test:unit</code></strong>: Run only the unit tests</li> <li><strong><code>test:features</code></strong>: Run only the features tests</li> <li><strong><code>test:single</code></strong>: Run only the single test case</li> <li><strong><code>coverage</code></strong>: Run only the unit tests and generate code coverage for them, the output will be on <code>coverage</code> folder</li> <li><strong><code>lint</code></strong>: Lint the codebase</li> <li><strong><code>sequelize</code></strong>: Alias to the <a href="https://github.com/sequelize/cli" target="_blank" rel="noopener">Sequelize CLI</a></li> <li><strong><code>console</code></strong>: Open the built-in console, you can access the DI container through the <code>container</code> variable once it's open, the console is promise-friendly. Click <a href="https://github.com/talyssonoc/node-api-boilerplate/wiki/Application-console" target="_blank" rel="noopener">here</a> to know more about the built-in console</li> </ul> <h3>Demo App:</h3> <ul> <li><a href="https://react-ipragmatech-ecommerce.herokuapp.com/" target="_blank" rel="noopener">Live Demo</a></li> </ul> [av_hr class='short' height='50' shadow='no-shadow' position='center' custom_border='av-border-thin' custom_width='50px' custom_border_color='' custom_margin_top='30px' custom_margin_bottom='30px' icon_select='yes' custom_icon_color='' icon='ue808' font='entypo-fontello' av_uid='av-3bdd715' custom_class='' admin_preview_bg=''] <h2>Conclusion</h2> In this article, you would know how to create an e-commerce app with react-redux. Create a UI in the React component. Redux manages the states and properties and the data is stored in the local or may use the Heroku. After reading this article, you will know that how can you run an e-commerce app. Feel free to ask any query, glad to hear from you. <h2>References</h2> <ul> <li><a href="https://github.com/ipragmatechadmin/React-Ecommerce-Builder" target="_blank" rel="noopener">React E-Commerce Builder</a></li> <li><a href="https://blog.usejournal.com/how-does-redux-work-b1cce46d4fa6">States and property management with Redux</a></li> </ul> <h2>Suggestions for further reading</h2> <ul> <li><a href="https://www.ipragmatech.com/how-effortlessly…app-react-nodejs/" target="_blank" rel="noopener">How effortlessly create free social media app like facebook</a></li> <li><a href="https://www.ipragmatech.com/backup-mysql-database-s3-bucket-script/">Easy and scalable solution for mysql database backup to AWS S3 bucket</a></li> <li><a href="https://developerlife.com/2016/10/07/getting-started-with-react-redux-and-firebase/">Building a real world app using React, Redux, Firebase, and Typescript</a></li> <li><a href="https://dusty.phillips.codes/2018/08/25/react-redux-firebase-with-firestore-tutorial/">React Redux Firebase With Firestore Tutorial</a></li> </ul> <br /><center><hr/><em>Posted from my blog with <a href='https://www.ipragmatech.com'></a> : https://www.ipragmatech.com/the-easiest-way-to-develop-a-free-e-commerce-app-using-react-and-nodejs/ </em><hr/></center>
json metadata{"community":"steempress","app":"steempress","image":[""],"tags":["ipragmatech","e-commerce","e-commerceapp","node-js"],"original_link":"https://www.ipragmatech.com/the-easiest-way-to-develop-a-free-e-commerce-app-using-react-and-nodejs/"}
parent author
parent permlinkipragmatech
permlinktheeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag
titleThe Easiest way to develop a free e-commerce app using React and Nodejs.
Transaction InfoBlock #34619291/Trx 5598cedaf4f54cc70e913f375c26d83c1acef5b3
View Raw JSON Data
{
  "block": 34619291,
  "op": [
    "comment",
    {
      "author": "ipragmatech",
      "body": "<center>http://www.ipragmatech.com/wp-content/uploads/2019/07/react-e-commerce.png</center> <br/>There are also a few frontend platforms into which you can integrate e-commerce functionalities, like <a href=\"https://snipcart.com/blog/react-seo-nextjs-tutorial\">Next.js</a>, a lightweight framework for static and server-rendered apps. Finally, we’ve chosen for this post? React E-commerce Builder. We’ll integrate it with our shopping cart for developers. The result <strong>should</strong> be a neat, React-powered e-commerce app!\r\n<h2>Why Should you use React for e-commerce?</h2>\r\nA common E-commerce website usually comprises a plethora of forms to fill, complex filters, elements, which interact with different APIs, maps, etc. With the help of React, you can easily implement all of those features, making it a good option to build highly interactive E-commerce websites.\r\n\r\nOne of the great things about React is that it allows for a rather convenient way of storing and manipulating the state of your app (e.g. filtering through items is a change in the state of the app). What’s more, React comes with a whole bunch of ready-made modules for all occasions, not mentioning that it’s easy to test and scale.\r\n\r\nIt has been at the forefront of frontend web development for a few years now. It boasts a constellation of stars at the top of its GitHub repo. It’s used by tech behemoths like Airbnb, Netflix, and Instagram. It was created by Facebook developers for Pete’s sake! Saying it’s trendy is an understatement.\r\n\r\nReact has proven its awesomeness more than enough. With its component-centric development, Virtual DOM, JSX syntax, etc. it has changed frontend development for the best.\r\n<h3>Features:</h3>\r\n<ul>\r\n <li>\r\n<h4><strong>The use of components for flexibility: </strong></h4>\r\nComponent-based development enables easy code reuse through your app, but also the writing of small features. Or, in our case, small e-commerce functionalities. This comes in handy once you start scaling and expanding your shopping cart integration. I’ll show you a concrete example in the demo further down.</li>\r\n</ul>\r\n<ul>\r\n <li>\r\n<h4><strong>Virtual DOM for performance: </strong></h4>\r\nReact’s <a class=\"external-link\" href=\"https://www.rigelnetworks.com/using-virtual-dom-react-js-top-5-benefits/\" target=\"_blank\" rel=\"noopener\">virtual DOM</a> provides a more efficient way of updating the view in a web application. Performance is HUGE in e-commerce; every milli-seconds count. Speed = Better UX/SEO = $$$.</li>\r\n</ul>\r\n<ul>\r\n <li>\r\n<h4><strong>Popularity &amp; vast community for peace of mind: </strong></h4>\r\nIf you’re a merchant, it shouldn’t be too hard finding developers to maintain your React e-commerce app. If you’re a developer, any issue has probably already been documented. Also, the ecosystem has spawned dozens of excellent dev tools to optimize React development.</li>\r\n <li>\r\n<h4><strong><strong>Have a look at React e-commer</strong>ce tools: </strong></h4>\r\nA couple of solutions will let you kickstart your e-commerce development with React:\r\n<ul>\r\n <li><a class=\"external-link\" href=\"https://moltin.com/react-js/\" target=\"_blank\" rel=\"noopener\"><strong>Moltin</strong></a> <strong>-</strong> An API-based e-commerce solution. It allows you to use React natively to power your applications.</li>\r\n <li><a class=\"external-link\" href=\"https://cezerin.com/\" target=\"_blank\" rel=\"noopener\"><strong>Cezerin</strong></a> <strong>-</strong> A React &amp; Node.js-based e-commerce platform. Enables the creation of PWAs.</li>\r\n <li><a class=\"external-link\" href=\"https://www.reactioncommerce.com/\" target=\"_blank\" rel=\"noopener\"><strong>Reaction Commerce</strong></a> <strong>-</strong> Open-source, real-time platform. Built on Node.js, but plays nice with React.</li>\r\n</ul>\r\n</li>\r\n</ul>\r\nReact E-commerce Builder is a React and Node.js based eCommerce platform. The project has two components i.e. <a href=\"https://github.com/ipragmatechadmin/React-Ecommerce-Builder/tree/master/client\" target=\"_blank\" rel=\"noopener\">client (react)</a> and <a href=\"https://github.com/ipragmatechadmin/React-Ecommerce-Builder/tree/master/server\" target=\"_blank\" rel=\"noopener\">server-side (node.js)</a>. Please download or clone the respective components and follow the instructions for the setup.\r\n<h2>Client:</h2>\r\nThe React E-commerce is a project relying on [<a href=\"https://facebook.github.io/react/docs/hello-world.html\" target=\"_blank\" rel=\"noopener\">React]</a> a powerful javascript library for building the user interface. In this project, I tried to show some features of react/react components as an e-commerce platform. The structure of this project gives the ability to the developer to develop their project on their own idea and environment.\r\n<h3>Features:</h3>\r\n<ul>\r\n <li>Product listing</li>\r\n <li><center><img class=\"aligncenter wp-image-26114 size-full\" src=\"http://www.ipragmatech.com/wp-content/uploads/2019/07/ProductList.png\" alt=\"\" width=\"825\" height=\"777\" /></center><br/></li>\r\n <li>Search the product by text</li>\r\n <li>Product Details</li>\r\n <li>SignIn and Signup</li>\r\n <li>Add to cart</li>\r\n <li>Payment through PayPal</li>\r\n <li>Update Shipping Details</li>\r\n</ul>\r\n<h3>Structure:</h3>\r\nThe current structure could make the project easy to change and scale up. Using the current structure we are able to develop the mobile app in parallel with web app <strong>only</strong> with changing <code>Components</code> layer. It means we can keep <code>Core</code>, <code>Data</code> layers, <code>Actions</code>, <code>Reducers</code>, etc. What we have high reusability and fast in producing the products. So here is the structure of the project:\r\n\r\nThese instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.\r\n<h3><a id=\"user-content-prerequisites\" class=\"anchor\" href=\"https://github.com/ipragmatechadmin/React-Ecommerce-Builder/tree/master/client#prerequisites\" aria-hidden=\"true\"></a>Prerequisites</h3>\r\nInstall <a href=\"https://nodejs.org/en/\" target=\"_blank\" rel=\"nofollow noopener\">NodeJs</a>\r\n<h4><a id=\"user-content-note\" class=\"anchor\" href=\"https://github.com/ipragmatechadmin/React-Ecommerce-Builder/tree/master/client#note\" aria-hidden=\"true\"></a>Note</h4>\r\n<ul>\r\n <li>If you're using Windows you should install all node-gyp dependencies with following commands:</li>\r\n <li><script src=\"https://gist.github.com/Abhiranjanchaurasia/1b95ed6c3d28c484a08078aefe80e15f.js\"></script></li>\r\n <li>and then install the package</li>\r\n <li><script src=\"https://gist.github.com/Abhiranjanchaurasia/7097aadbbf7c01538c07b6ec86754c52.js\"></script></li>\r\n</ul>\r\n<h3><a id=\"user-content-installing\" class=\"anchor\" href=\"https://github.com/ipragmatechadmin/React-Ecommerce-Builder/tree/master/client#installing\" aria-hidden=\"true\"></a>Installing</h3>\r\n<ul>\r\n <li>Download the source code file or clone it from <a href=\"https://github.com/ipragmatechadmin/React-Ecommerce-Builder\" target=\"_blank\" rel=\"noopener\">https://github.com/ipragmatechadmin/React-Ecommerce-Builder.</a></li>\r\n <li>Go to the project root directory</li>\r\n <li><script src=\"https://gist.github.com/Abhiranjanchaurasia/b71859fb33648cbf5fbcecb5a3830056.js\"></script></li>\r\n <li>To install node dependencies use</li>\r\n <li><script src=\"https://gist.github.com/Abhiranjanchaurasia/c5d9c21be1ad461a0358d668e13e2e06.js\"></script></li>\r\n <li>Open environment config and set the APIs URL. React E-commerce is able to be connected with current Node Web APIs.</li>\r\n <li>Once done we are ready to use the e-commerce app.\r\n<script src=\"https://gist.github.com/Abhiranjanchaurasia/34f8c71bb10d272cd4c87af209cd76fb.js\"></script></li>\r\n</ul>\r\n[av_hr class='short' height='50' shadow='no-shadow' position='center' custom_border='av-border-thin' custom_width='50px' custom_border_color='' custom_margin_top='30px' custom_margin_bottom='30px' icon_select='yes' custom_icon_color='' icon='ue808' font='entypo-fontello' av_uid='av-3bdd715' custom_class='' admin_preview_bg='']\r\n<h2>Server:</h2>\r\nAn eCommerce platform for Node web APIs focused on the separation of concerns and scalability. The app is deployed on Heroku and APIs documentation is available at <a href=\"https://ipragmatech-ecommmerce.herokuapp.com/api/docs\" target=\"_blank\" rel=\"nofollow noopener\">https://ipragmatech-ecommmerce.herokuapp.com/api/docs</a>\r\n<h3>Quick Start:</h3>\r\nThis platform has basic web APIs for the e-commerce app. The platform uses backend as a MySQL database but can be used for other platforms like firebase, dynamodb, etc.\r\n<ul>\r\n <li>Download the source code file or clone it from <a href=\"https://github.com/ipragmatechadmin/React-Ecommerce-Builder\" target=\"_blank\" rel=\"noopener\">https://github.com/ipragmatechadmin/React-Ecommerce-Builder</a>.</li>\r\n <li>Setup the database on <code>config/database.js</code> with the MySQL database configurations.</li>\r\n <li>Go to the root directory  server</li>\r\n <li><script src=\"https://gist.github.com/Abhiranjanchaurasia/726a7feed5b57457a525f705515d4e44.js\"></script></li>\r\n <li>Install the dependencies with <code>yarn</code> or npm (click here if <a href=\"https://yarnpkg.com/docs/install\" target=\"_blank\" rel=\"nofollow noopener\">you don't have Yarn installed</a>)</li>\r\n <li><script src=\"https://gist.github.com/Abhiranjanchaurasia/c5d9c21be1ad461a0358d668e13e2e06.js\"></script></li>\r\n <li>Create the development and test databases you have set up on <code>config/database.js</code>:</li>\r\n <li><script src=\"https://gist.github.com/Abhiranjanchaurasia/9bb2d7d8f180bbad2da953ec4f12d05b.js\"></script></li>\r\n <li>Run the database script located at <code>src/infra/database scripts</code>. This shall create the sample data along with tables and stored procedures.</li>\r\n <li>If MySQL is not present with the local system, download the MYSQL to the system.</li>\r\n <li>Start the MYSQL Server and import the database tables like:</li>\r\n <li><script src=\"https://gist.github.com/Abhiranjanchaurasia/2292c911a6e5b65ca0faa8b59a65026b.js\"></script></li>\r\n <li>For Database backup, there is a need to export the database like:</li>\r\n <li><script src=\"https://gist.github.com/Abhiranjanchaurasia/b75dd19395d82c679ba0b7079f7368e0.js\"></script></li>\r\n <li>Run the application in development mode with <code>npm run dev</code></li>\r\n <li>Access <code>http://localhost:3000/api/docs</code> and you can check the APIs documentation. You can test the APIs by changing the base URL. you're ready to go!</li>\r\n</ul>\r\n<h3>Script:</h3>\r\nThis boilerplate comes with a collection of npm scripts to make your life easier, you'll run them with <code>npm run &lt;script name&gt;</code> or <code>yarn run &lt;script name&gt;</code>:\r\n<ul>\r\n <li><strong><code>dev</code></strong>: Run the application in development mode</li>\r\n <li><strong><code>start</code></strong> Run the application in production mode (prefer not to do that in development)</li>\r\n <li><strong><code>test</code></strong>: Run the test suite</li>\r\n <li><strong><code>test:unit</code></strong>: Run only the unit tests</li>\r\n <li><strong><code>test:features</code></strong>: Run only the features tests</li>\r\n <li><strong><code>test:single</code></strong>: Run only the single test case</li>\r\n <li><strong><code>coverage</code></strong>: Run only the unit tests and generate code coverage for them, the output will be on <code>coverage</code> folder</li>\r\n <li><strong><code>lint</code></strong>: Lint the codebase</li>\r\n <li><strong><code>sequelize</code></strong>: Alias to the <a href=\"https://github.com/sequelize/cli\" target=\"_blank\" rel=\"noopener\">Sequelize CLI</a></li>\r\n <li><strong><code>console</code></strong>: Open the built-in console, you can access the DI container through the <code>container</code> variable once it's open, the console is promise-friendly. Click <a href=\"https://github.com/talyssonoc/node-api-boilerplate/wiki/Application-console\" target=\"_blank\" rel=\"noopener\">here</a> to know more about the built-in console</li>\r\n</ul>\r\n<h3>Demo App:</h3>\r\n<ul>\r\n <li><a href=\"https://react-ipragmatech-ecommerce.herokuapp.com/\" target=\"_blank\" rel=\"noopener\">Live Demo</a></li>\r\n</ul>\r\n[av_hr class='short' height='50' shadow='no-shadow' position='center' custom_border='av-border-thin' custom_width='50px' custom_border_color='' custom_margin_top='30px' custom_margin_bottom='30px' icon_select='yes' custom_icon_color='' icon='ue808' font='entypo-fontello' av_uid='av-3bdd715' custom_class='' admin_preview_bg='']\r\n<h2>Conclusion</h2>\r\nIn this article, you would know how to create an e-commerce app with react-redux. Create a UI in the React component. Redux manages the states and properties and the data is stored in the local or may use the Heroku. After reading this article, you will know that how can you run an e-commerce app. Feel free to ask any query, glad to hear from you.\r\n<h2>References</h2>\r\n<ul>\r\n <li><a href=\"https://github.com/ipragmatechadmin/React-Ecommerce-Builder\" target=\"_blank\" rel=\"noopener\">React E-Commerce Builder</a></li>\r\n <li><a href=\"https://blog.usejournal.com/how-does-redux-work-b1cce46d4fa6\">States and property management with Redux</a></li>\r\n</ul>\r\n<h2>Suggestions for further reading</h2>\r\n<ul>\r\n <li><a href=\"https://www.ipragmatech.com/how-effortlessly…app-react-nodejs/\" target=\"_blank\" rel=\"noopener\">How effortlessly create free social media app like facebook</a></li>\r\n <li><a href=\"https://www.ipragmatech.com/backup-mysql-database-s3-bucket-script/\">Easy and scalable solution for mysql database backup to AWS S3 bucket</a></li>\r\n <li><a href=\"https://developerlife.com/2016/10/07/getting-started-with-react-redux-and-firebase/\">Building a real world app using React, Redux, Firebase, and Typescript</a></li>\r\n <li><a href=\"https://dusty.phillips.codes/2018/08/25/react-redux-firebase-with-firestore-tutorial/\">React Redux Firebase With Firestore Tutorial</a></li>\r\n</ul> <br /><center><hr/><em>Posted from my blog with <a href='https://www.ipragmatech.com'></a> : https://www.ipragmatech.com/the-easiest-way-to-develop-a-free-e-commerce-app-using-react-and-nodejs/ </em><hr/></center>   ",
      "json_metadata": "{\"community\":\"steempress\",\"app\":\"steempress\",\"image\":[\"\"],\"tags\":[\"ipragmatech\",\"e-commerce\",\"e-commerceapp\",\"node-js\"],\"original_link\":\"https://www.ipragmatech.com/the-easiest-way-to-develop-a-free-e-commerce-app-using-react-and-nodejs/\"}",
      "parent_author": "",
      "parent_permlink": "ipragmatech",
      "permlink": "theeasiestwaytodevelopafreee-commerceappusingreactandnodejs-px8lp0byag",
      "title": "The Easiest way to develop a free e-commerce app using React and Nodejs."
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-13T06:50:57",
  "trx_id": "5598cedaf4f54cc70e913f375c26d83c1acef5b3",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 5.991 SP to @ipragmatech
2019/06/07 07:37:24
delegateeipragmatech
delegatorsteem
vesting shares9756.286181 VESTS
Transaction InfoBlock #33584923/Trx 31a26523dc5ea49f23b7e516c2767f7bb03a4f87
View Raw JSON Data
{
  "block": 33584923,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "9756.286181 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-06-07T07:37:24",
  "trx_id": "31a26523dc5ea49f23b7e516c2767f7bb03a4f87",
  "trx_in_block": 19,
  "virtual_op": 0
}
steemdelegated 18.224 SP to @ipragmatech
2019/06/07 05:17:39
delegateeipragmatech
delegatorsteem
vesting shares29675.801033 VESTS
Transaction InfoBlock #33582132/Trx c8fc83ea52d9ab6c1f659106789c1de99e87c271
View Raw JSON Data
{
  "block": 33582132,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "29675.801033 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-06-07T05:17:39",
  "trx_id": "c8fc83ea52d9ab6c1f659106789c1de99e87c271",
  "trx_in_block": 31,
  "virtual_op": 0
}
2019/05/26 05:06:21
authorsteemitboard
bodyCongratulations @ipragmatech! You received a personal award! <table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@ipragmatech/birthday1.png</td><td>Happy Birthday! - You are on the Steem blockchain for 1 year!</td></tr></table> <sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@ipragmatech) and compare to others on the [Steem Ranking](http://steemitboard.com/ranking/index.php?name=ipragmatech)_</sub> ###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
parent authoripragmatech
parent permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
permlinksteemitboard-notify-ipragmatech-20190526t050620000z
title
Transaction InfoBlock #33236665/Trx 3aafbaf505a63326977685f91ba5e52ff981f7b0
View Raw JSON Data
{
  "block": 33236665,
  "op": [
    "comment",
    {
      "author": "steemitboard",
      "body": "Congratulations @ipragmatech! You received a personal award!\n\n<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@ipragmatech/birthday1.png</td><td>Happy Birthday! - You are on the Steem blockchain for 1 year!</td></tr></table>\n\n<sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@ipragmatech) and compare to others on the [Steem Ranking](http://steemitboard.com/ranking/index.php?name=ipragmatech)_</sub>\n\n\n###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}",
      "parent_author": "ipragmatech",
      "parent_permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "permlink": "steemitboard-notify-ipragmatech-20190526t050620000z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-05-26T05:06:21",
  "trx_id": "3aafbaf505a63326977685f91ba5e52ff981f7b0",
  "trx_in_block": 1,
  "virtual_op": 0
}
steemdelegated 6.013 SP to @ipragmatech
2019/04/08 10:28:03
delegateeipragmatech
delegatorsteem
vesting shares9791.103170 VESTS
Transaction InfoBlock #31862729/Trx 29da8a075875ea89bc160beb36df5408a0601e77
View Raw JSON Data
{
  "block": 31862729,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "9791.103170 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-04-08T10:28:03",
  "trx_id": "29da8a075875ea89bc160beb36df5408a0601e77",
  "trx_in_block": 10,
  "virtual_op": 0
}
steemdelegated 18.353 SP to @ipragmatech
2019/02/06 04:36:36
delegateeipragmatech
delegatorsteem
vesting shares29885.780788 VESTS
Transaction InfoBlock #30100482/Trx d5e4391fca51fe4627342276d048abceef3e3e84
View Raw JSON Data
{
  "block": 30100482,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "ipragmatech",
      "delegator": "steem",
      "vesting_shares": "29885.780788 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-02-06T04:36:36",
  "trx_id": "d5e4391fca51fe4627342276d048abceef3e3e84",
  "trx_in_block": 12,
  "virtual_op": 0
}
2019/01/18 09:36:39
authorpartiko
body[![](https://d1vof77qrk4l5q.cloudfront.net/statics/upsell-delegate-15-steem-power-2.png)](https://partiko-io.app.link/A27hLeUkgT)
json metadata{"app":"partiko"}
parent authoripragmatech
parent permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
permlinkpartiko-re-ipragmatech-howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00-20190118t093639718z
title
Transaction InfoBlock #29559837/Trx ef6fd581670bd6600c7a6af39fc286fa98ae2aa8
View Raw JSON Data
{
  "block": 29559837,
  "op": [
    "comment",
    {
      "author": "partiko",
      "body": "[![](https://d1vof77qrk4l5q.cloudfront.net/statics/upsell-delegate-15-steem-power-2.png)](https://partiko-io.app.link/A27hLeUkgT)",
      "json_metadata": "{\"app\":\"partiko\"}",
      "parent_author": "ipragmatech",
      "parent_permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "permlink": "partiko-re-ipragmatech-howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00-20190118t093639718z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-18T09:36:39",
  "trx_id": "ef6fd581670bd6600c7a6af39fc286fa98ae2aa8",
  "trx_in_block": 9,
  "virtual_op": 0
}
ipragmatechreceived 0.532 STEEM, 0.007 SBD, 0.685 SP author reward for @ipragmatech / howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
2019/01/14 09:03:24
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
sbd payout0.007 SBD
steem payout0.532 STEEM
vesting payout1114.753914 VESTS
Transaction InfoBlock #29444107/Virtual Operation #25
View Raw JSON Data
{
  "block": 29444107,
  "op": [
    "author_reward",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "sbd_payout": "0.007 SBD",
      "steem_payout": "0.532 STEEM",
      "vesting_payout": "1114.753914 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-14T09:03:24",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 25
}
steempressreceived 0.121 SP benefactor reward from @ipragmatech
2019/01/14 09:03:24
authoripragmatech
benefactorsteempress
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
sbd payout0.001 SBD
steem payout0.094 STEEM
vesting payout196.839430 VESTS
Transaction InfoBlock #29444107/Virtual Operation #24
View Raw JSON Data
{
  "block": 29444107,
  "op": [
    "comment_benefactor_reward",
    {
      "author": "ipragmatech",
      "benefactor": "steempress",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "sbd_payout": "0.001 SBD",
      "steem_payout": "0.094 STEEM",
      "vesting_payout": "196.839430 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-14T09:03:24",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 24
}
ipragmatechreceived 0.345 STEEM, 0.001 SBD, 0.431 SP author reward for @ipragmatech / easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
2019/01/11 16:55:48
authoripragmatech
permlinkeasilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
sbd payout0.001 SBD
steem payout0.345 STEEM
vesting payout701.093456 VESTS
Transaction InfoBlock #29367205/Virtual Operation #8
View Raw JSON Data
{
  "block": 29367205,
  "op": [
    "author_reward",
    {
      "author": "ipragmatech",
      "permlink": "easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7",
      "sbd_payout": "0.001 SBD",
      "steem_payout": "0.345 STEEM",
      "vesting_payout": "701.093456 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-11T16:55:48",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 8
}
steempressreceived 0.075 SP benefactor reward from @ipragmatech
2019/01/11 16:55:48
authoripragmatech
benefactorsteempress
permlinkeasilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
sbd payout0.000 SBD
steem payout0.061 STEEM
vesting payout122.540690 VESTS
Transaction InfoBlock #29367205/Virtual Operation #7
View Raw JSON Data
{
  "block": 29367205,
  "op": [
    "comment_benefactor_reward",
    {
      "author": "ipragmatech",
      "benefactor": "steempress",
      "permlink": "easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.061 STEEM",
      "vesting_payout": "122.540690 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-11T16:55:48",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 7
}
ipragmatechreceived 0.374 STEEM, 0.001 SBD, 0.465 SP author reward for @ipragmatech / chooseyourimageloaderaccordingtoyourandroidappsmartly-kpo9fe11uf
2019/01/07 09:31:36
authoripragmatech
permlinkchooseyourimageloaderaccordingtoyourandroidappsmartly-kpo9fe11uf
sbd payout0.001 SBD
steem payout0.374 STEEM
vesting payout757.523182 VESTS
Transaction InfoBlock #29243181/Virtual Operation #12
View Raw JSON Data
{
  "block": 29243181,
  "op": [
    "author_reward",
    {
      "author": "ipragmatech",
      "permlink": "chooseyourimageloaderaccordingtoyourandroidappsmartly-kpo9fe11uf",
      "sbd_payout": "0.001 SBD",
      "steem_payout": "0.374 STEEM",
      "vesting_payout": "757.523182 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:31:36",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 12
}
steempressreceived 0.081 SP benefactor reward from @ipragmatech
2019/01/07 09:31:36
authoripragmatech
benefactorsteempress
permlinkchooseyourimageloaderaccordingtoyourandroidappsmartly-kpo9fe11uf
sbd payout0.000 SBD
steem payout0.066 STEEM
vesting payout132.616790 VESTS
Transaction InfoBlock #29243181/Virtual Operation #11
View Raw JSON Data
{
  "block": 29243181,
  "op": [
    "comment_benefactor_reward",
    {
      "author": "ipragmatech",
      "benefactor": "steempress",
      "permlink": "chooseyourimageloaderaccordingtoyourandroidappsmartly-kpo9fe11uf",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.066 STEEM",
      "vesting_payout": "132.616790 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:31:36",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 11
}
2019/01/07 09:24:21
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
voterphusionphil
weight190 (1.90%)
Transaction InfoBlock #29243037/Trx 335b637dc90deae4e2ca4cd7616503e312f5fc12
View Raw JSON Data
{
  "block": 29243037,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "phusionphil",
      "weight": 190
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:24:21",
  "trx_id": "335b637dc90deae4e2ca4cd7616503e312f5fc12",
  "trx_in_block": 0,
  "virtual_op": 0
}
2019/01/07 09:23:42
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
votersteempress-io
weight262 (2.62%)
Transaction InfoBlock #29243024/Trx ddd0ee616f76205fe0e6f297696de15ab973adcf
View Raw JSON Data
{
  "block": 29243024,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "steempress-io",
      "weight": 262
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:23:42",
  "trx_id": "ddd0ee616f76205fe0e6f297696de15ab973adcf",
  "trx_in_block": 1,
  "virtual_op": 0
}
2019/01/07 09:23:33
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
votersteempress
weight262 (2.62%)
Transaction InfoBlock #29243021/Trx dd32593d5a17bb382a6986dcc84373772b69f3f4
View Raw JSON Data
{
  "block": 29243021,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "steempress",
      "weight": 262
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:23:33",
  "trx_id": "dd32593d5a17bb382a6986dcc84373772b69f3f4",
  "trx_in_block": 4,
  "virtual_op": 0
}
2019/01/07 09:22:24
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
voterfyrstikken
weight100 (1.00%)
Transaction InfoBlock #29242998/Trx 3bf2dec76f45baa607bff175db10a65b1f0e266f
View Raw JSON Data
{
  "block": 29242998,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "fyrstikken",
      "weight": 100
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:22:24",
  "trx_id": "3bf2dec76f45baa607bff175db10a65b1f0e266f",
  "trx_in_block": 23,
  "virtual_op": 0
}
2019/01/07 09:21:06
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
votereffofex
weight64 (0.64%)
Transaction InfoBlock #29242972/Trx 25bf77959323f562295bcf6640aa7737d85bff8f
View Raw JSON Data
{
  "block": 29242972,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "effofex",
      "weight": 64
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:21:06",
  "trx_id": "25bf77959323f562295bcf6640aa7737d85bff8f",
  "trx_in_block": 5,
  "virtual_op": 0
}
2019/01/07 09:20:18
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
voterascorphat
weight250 (2.50%)
Transaction InfoBlock #29242956/Trx e8c2274445b64b73e8138254e7c881e4d388ae32
View Raw JSON Data
{
  "block": 29242956,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "ascorphat",
      "weight": 250
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:20:18",
  "trx_id": "e8c2274445b64b73e8138254e7c881e4d388ae32",
  "trx_in_block": 31,
  "virtual_op": 0
}
2019/01/07 09:20:12
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
votermbappe
weight258 (2.58%)
Transaction InfoBlock #29242954/Trx 2e7d4736e1901afb364092158a4104af05e8804e
View Raw JSON Data
{
  "block": 29242954,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "mbappe",
      "weight": 258
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:20:12",
  "trx_id": "2e7d4736e1901afb364092158a4104af05e8804e",
  "trx_in_block": 16,
  "virtual_op": 0
}
2019/01/07 09:20:12
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
voterhamsa.quality
weight250 (2.50%)
Transaction InfoBlock #29242954/Trx c47eb90a3f31e3fcebc96e487afa0e5c5a85cb3e
View Raw JSON Data
{
  "block": 29242954,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "hamsa.quality",
      "weight": 250
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:20:12",
  "trx_id": "c47eb90a3f31e3fcebc96e487afa0e5c5a85cb3e",
  "trx_in_block": 15,
  "virtual_op": 0
}
2019/01/07 09:20:12
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
votermerlin7
weight34 (0.34%)
Transaction InfoBlock #29242954/Trx 935defd416c00e8b98452e7f285ca8476f68df58
View Raw JSON Data
{
  "block": 29242954,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "merlin7",
      "weight": 34
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:20:12",
  "trx_id": "935defd416c00e8b98452e7f285ca8476f68df58",
  "trx_in_block": 8,
  "virtual_op": 0
}
2019/01/07 09:20:12
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
voterespoem
weight400 (4.00%)
Transaction InfoBlock #29242954/Trx dd10c20c48589edb7401c9f22e27981cfe44a298
View Raw JSON Data
{
  "block": 29242954,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "espoem",
      "weight": 400
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:20:12",
  "trx_id": "dd10c20c48589edb7401c9f22e27981cfe44a298",
  "trx_in_block": 6,
  "virtual_op": 0
}
2019/01/07 09:20:12
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
voteraccelerator
weight129 (1.29%)
Transaction InfoBlock #29242954/Trx 005c5438dd6e60325f2e424963c86e8679249459
View Raw JSON Data
{
  "block": 29242954,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "accelerator",
      "weight": 129
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:20:12",
  "trx_id": "005c5438dd6e60325f2e424963c86e8679249459",
  "trx_in_block": 5,
  "virtual_op": 0
}
2019/01/07 09:19:30
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
voternfc
weight100 (1.00%)
Transaction InfoBlock #29242940/Trx 4ebd8a10320fd14504e535e964637af2222d57a6
View Raw JSON Data
{
  "block": 29242940,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "nfc",
      "weight": 100
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:19:30",
  "trx_id": "4ebd8a10320fd14504e535e964637af2222d57a6",
  "trx_in_block": 23,
  "virtual_op": 0
}
2019/01/07 09:06:33
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
votersteem.create
weight200 (2.00%)
Transaction InfoBlock #29242681/Trx 91f4e4540476a5f569d40d66f7da50b41622d533
View Raw JSON Data
{
  "block": 29242681,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "steem.create",
      "weight": 200
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:06:33",
  "trx_id": "91f4e4540476a5f569d40d66f7da50b41622d533",
  "trx_in_block": 12,
  "virtual_op": 0
}
2019/01/07 09:05:15
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
votersteeming-hot
weight25 (0.25%)
Transaction InfoBlock #29242655/Trx d3e2667af949279157ff5683e2da1b2d7ec7baed
View Raw JSON Data
{
  "block": 29242655,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "steeming-hot",
      "weight": 25
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:05:15",
  "trx_id": "d3e2667af949279157ff5683e2da1b2d7ec7baed",
  "trx_in_block": 18,
  "virtual_op": 0
}
2019/01/07 09:03:24
authoripragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
voteripragmatech
weight10000 (100.00%)
Transaction InfoBlock #29242618/Trx 27c1341434604e566ab46a73043ba0a3eb71b2bd
View Raw JSON Data
{
  "block": 29242618,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "voter": "ipragmatech",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:03:24",
  "trx_id": "27c1341434604e566ab46a73043ba0a3eb71b2bd",
  "trx_in_block": 39,
  "virtual_op": 0
}
2019/01/07 09:03:24
allow curation rewardstrue
allow votestrue
authoripragmatech
extensions[[0,{"beneficiaries":[{"account":"steempress","weight":1500}]}]]
max accepted payout1000000.000 SBD
percent steem dollars10000
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
Transaction InfoBlock #29242618/Trx 27c1341434604e566ab46a73043ba0a3eb71b2bd
View Raw JSON Data
{
  "block": 29242618,
  "op": [
    "comment_options",
    {
      "allow_curation_rewards": true,
      "allow_votes": true,
      "author": "ipragmatech",
      "extensions": [
        [
          0,
          {
            "beneficiaries": [
              {
                "account": "steempress",
                "weight": 1500
              }
            ]
          }
        ]
      ],
      "max_accepted_payout": "1000000.000 SBD",
      "percent_steem_dollars": 10000,
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:03:24",
  "trx_id": "27c1341434604e566ab46a73043ba0a3eb71b2bd",
  "trx_in_block": 39,
  "virtual_op": 0
}
2019/01/07 09:03:24
authoripragmatech
body<center>http://www.ipragmatech.com/wp-content/uploads/2018/11/Screenshot-2018-11-22-at-3.48.49-PM-e1544158233557.png</center> <br/>Recently, we were working on a social app of one of our clients. Their requirement was to add map feature in the app and especially HereMap. To integrate HereMap iOS SDK in the app was a great experience for our team. In this guide, we will give you a detailed information about integrating the HereMap iOS SDK in your iOS app. <p class="p1"><b>What is the HERE iOS SDK?</b></p> <p class="p2">The HereMap iOS SDK provides a set of programming interfaces that enable developers to build immersive, geographically-aware iOS applications by leveraging a powerful and flexible mapping platform. Through this SDK, developers can add rich location features such as routing, interactive maps, and global place search to their applications. The powerful client-side HereMap iOS SDK also includes a sophisticated engine for rendering map data and calculated routes.</p> <b>Feature Lists</b> The main features offered by the HereMap iOS SDK are listed below. <b>Mapping:</b> <ul class="ul1"> <li class="li1">Raster map tiles with high resolution support.</li> <li class="li1">Map styles: Normal, Satellite, Terrain, and more.</li> <li class="li1">Touch gestures such as tap, pan, and pinch.</li> <li class="li1">Overlay objects on the map such as polylines, polygons, icons, routes.</li> </ul> <b>Search:</b> <ul class="ul1"> <li class="li1">Search through a broad set of geographical content across the globe (including streets, address points, and categorized places).</li> <li class="li1">User can Search Places for somewhere specific or explore by categories.</li> <li class="li1">Access rich details for a Point of Interest from third-party content sources (including images, ratings, reviews, and editorials).</li> <li class="li1">Perform geocoding and reverse geocoding lookups.</li> </ul> <b>Directions:</b> <ul class="ul1"> <li class="li1">Online Car and Pedestrian Route Directions.</li> <li class="li1">Specify preferred route type (fastest or shortest) and route options (such as avoiding toll roads, motorways, and parks).</li> <li class="li1">Alternate routes.</li> </ul> <b>Legal Requirements</b> <p class="p1">In addition to the applicable <a href="https://developer.here.com/terms-and-conditions">terms and conditions</a> under which you have licensed the SDK, the following shall apply:   AppId and AppCode – You may  see on  <a href="https://developer.here.com/documentation/ios-starter/dev_guide/topics/credentials.html">Authenticating Applications</a> .</p> <b>System Requirements</b> <ul class="ul1"> <li class="li1">HereMap SDK supports iOS 11 or above. iOS 12 is recommended for optimal operation.</li> <li class="li1">It is designed and tested for use with iOS phones and tablets. Supported devices are: <ul class="ul1"> <li class="li1">iPhone 5 or newer</li> <li class="li1">iPad 3 or newer</li> <li class="li1">iPad Mini 2 or newer</li> </ul> </li> <li class="li1">Apps should be developed using XCode 10 or above, running on macOS 10.13.6 or above.</li> </ul> <b>Tasks for this basic application include:</b> <ul class="ul1"> <li class="li1">Acquire HERE Credentials.</li> <li class="li1">Launch the sample project using CocoaPods or manually from the package.</li> </ul> <h2>Steps To Implements HereMap In iOS Map:</h2> <p class="p1"><b>1. Acquire HereMap SDK Credentials</b></p> <p class="p1">Before working with with HERE SDK, you need to acquire a set of credentials by registering your application on <a href="http://developer.here.com/">http://developer.here.com</a>. Each application requires a unique set of credentials.</p> <p class="p1"><b>2. Create an NMAMapView</b></p> <p class="p1">Select Main.storyboard in the navigator. Add the import statement to the top of this file:<b>@import NMAKit;</b> Name the outlet mapView, keep the other default options and then select Connect.</p> <p class="p1"><b>3. Now an outlet to NMAMapView is set. The modified file should be as follows:</b></p> <pre>#import "HelloMapViewController.h" @import NMAKit; @interface HelloMapViewController () @property (weak, nonatomic) IBOutlet NMAMapView *mapView; @end @implementation HelloMapViewController - (void)viewDidLoad {   [super viewDidLoad]; } - (void)didReceiveMemoryWarning {   [super didReceiveMemoryWarning]; } @end</pre> <p class="p1"><b>4. Implement NMAMapView setup and lifecycle code by modifying the viewDidLoad method as shown:- </b></p> <pre>(void)viewDidLoad {   [super viewDidLoad];   //set geo center   NMAGeoCoordinates *geoCoordCenter =     [[NMAGeoCoordinates alloc] initWithLatitude:49.260327 longitude:-123.115025];   [self.mapView setGeoCenter:geoCoordCenter withAnimation:NMAMapAnimationNone];   self.mapView.copyrightLogoPosition = NMALayoutPositionBottomCenter;   //set zoom level   self.mapView.zoomLevel = 13.2; }</pre> <p class="p1"><b>5. Add your HERE application credentials.</b></p> <ol class="ol1"> <li class="li1">Open AppDelegate.m and import NMAKit by adding the following import statement to the top of the file.@import NMAKit;</li> <li class="li1">Add the following in the didFinishLaunchingWithOptions method, replacing YOUR_APP_ID and YOUR_APP_CODE with the credentials that you received from <a href="http://developer.here.com/">http://developer.here.com</a>.[NMAApplicationContext setAppId:@"<a href="https://developer.here.com/documentation/ios-starter/dev_guide/topics/app-create-simple.html?insertAppId">{YOUR_APP_ID}</a>"  appCode:@"<a href="https://developer.here.com/documentation/ios-starter/dev_guide/topics/app-create-simple.html?insertAppId">{YOUR_APP_CODE}</a>"];.</li> </ol> <p class="p1"><b>Conclusion</b></p> <p class="p1">Hope this article would help you understand the HereMap SDK integration in depth. There are various methods provided by the SDK to use its mapping and location changing properties. You can take help from the documentation provided by the platform itself, below are some references for its documentation.</p> <p class="p2"><strong>References</strong></p> <p class="p3"><a href="https://developer.here.com/documentation/android-starter/dev_guide/topics/maps.html">HERE iOS SDK</a></p> <p class="p3"><a href="https://github.com/heremaps/here-ios-sdk-examples">HERE Map Github</a></p> <p class="p2"><strong>Further Reading</strong></p> <p class="p3"><a href="https://www.ipragmatech.com/how-to-build-website-quickly-platform-over-custom-development/">How to build a website quickly using Platform over Custom development?</a></p> <p class="p3"><a href="https://www.ipragmatech.com/?p=25062&amp;preview=true">How Easy To Implement DZVideoPlayer in iOS App</a></p> <br /><center><hr/><em>Posted from my blog with <a href='https://www.ipragmatech.com'></a> : https://www.ipragmatech.com/how-easy-to-integrate-heremap-sdk-os-application/ </em><hr/></center>
json metadata{"community":"steempress","app":"steempress/1.4","image":[""],"tags":["ipragmatech"],"original_link":"https://www.ipragmatech.com/how-easy-to-integrate-heremap-sdk-os-application/"}
parent author
parent permlinkipragmatech
permlinkhoweasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00
titleHow Easy To Integrate HereMap SDK In iOS App, Read This!
Transaction InfoBlock #29242618/Trx 27c1341434604e566ab46a73043ba0a3eb71b2bd
View Raw JSON Data
{
  "block": 29242618,
  "op": [
    "comment",
    {
      "author": "ipragmatech",
      "body": "<center>http://www.ipragmatech.com/wp-content/uploads/2018/11/Screenshot-2018-11-22-at-3.48.49-PM-e1544158233557.png</center> <br/>Recently, we were working on a social app of one of our clients. Their requirement was to add map feature in the app and especially HereMap. To integrate HereMap iOS SDK in the app was a great experience for our team. In this guide, we will give you a detailed information about integrating the HereMap iOS SDK in your iOS app.\r\n<p class=\"p1\"><b>What is the HERE iOS SDK?</b></p>\r\n<p class=\"p2\">The HereMap iOS SDK provides a set of programming interfaces that enable developers to build immersive, geographically-aware iOS applications by leveraging a powerful and flexible mapping platform. Through this SDK, developers can add rich location features such as routing, interactive maps, and global place search to their applications. The powerful client-side HereMap iOS SDK also includes a sophisticated engine for rendering map data and calculated routes.</p>\r\n<b>Feature Lists</b>\r\n\r\nThe main features offered by the HereMap iOS SDK are listed below.\r\n\r\n<b>Mapping:</b>\r\n<ul class=\"ul1\">\r\n <li class=\"li1\">Raster map tiles with high resolution support.</li>\r\n <li class=\"li1\">Map styles: Normal, Satellite, Terrain, and more.</li>\r\n <li class=\"li1\">Touch gestures such as tap, pan, and pinch.</li>\r\n <li class=\"li1\">Overlay objects on the map such as polylines, polygons, icons, routes.</li>\r\n</ul>\r\n<b>Search:</b>\r\n<ul class=\"ul1\">\r\n <li class=\"li1\">Search through a broad set of geographical content across the globe (including streets, address points, and categorized places).</li>\r\n <li class=\"li1\">User can Search Places for somewhere specific or explore by categories.</li>\r\n <li class=\"li1\">Access rich details for a Point of Interest from third-party content sources (including images, ratings, reviews, and editorials).</li>\r\n <li class=\"li1\">Perform geocoding and reverse geocoding lookups.</li>\r\n</ul>\r\n<b>Directions:</b>\r\n<ul class=\"ul1\">\r\n <li class=\"li1\">Online Car and Pedestrian Route Directions.</li>\r\n <li class=\"li1\">Specify preferred route type (fastest or shortest) and route options (such as avoiding toll roads, motorways, and parks).</li>\r\n <li class=\"li1\">Alternate routes.</li>\r\n</ul>\r\n<b>Legal Requirements</b>\r\n<p class=\"p1\">In addition to the applicable <a href=\"https://developer.here.com/terms-and-conditions\">terms and conditions</a> under which you have licensed the SDK, the following shall apply:   AppId and AppCode – You may  see on  <a href=\"https://developer.here.com/documentation/ios-starter/dev_guide/topics/credentials.html\">Authenticating Applications</a> .</p>\r\n<b>System Requirements</b>\r\n<ul class=\"ul1\">\r\n <li class=\"li1\">HereMap SDK supports iOS 11 or above. iOS 12 is recommended for optimal operation.</li>\r\n <li class=\"li1\">It is designed and tested for use with iOS phones and tablets. Supported devices are:\r\n<ul class=\"ul1\">\r\n <li class=\"li1\">iPhone 5 or newer</li>\r\n <li class=\"li1\">iPad 3 or newer</li>\r\n <li class=\"li1\">iPad Mini 2 or newer</li>\r\n</ul>\r\n</li>\r\n <li class=\"li1\">Apps should be developed using XCode 10 or above, running on macOS 10.13.6 or above.</li>\r\n</ul>\r\n<b>Tasks for this basic application include:</b>\r\n<ul class=\"ul1\">\r\n <li class=\"li1\">Acquire HERE Credentials.</li>\r\n <li class=\"li1\">Launch the sample project using CocoaPods or manually from the package.</li>\r\n</ul>\r\n<h2>Steps To Implements HereMap In iOS Map:</h2>\r\n<p class=\"p1\"><b>1. Acquire HereMap SDK Credentials</b></p>\r\n<p class=\"p1\">Before working with with HERE SDK, you need to acquire a set of credentials by registering your application on <a href=\"http://developer.here.com/\">http://developer.here.com</a>. Each application requires a unique set of credentials.</p>\r\n<p class=\"p1\"><b>2. Create an NMAMapView</b></p>\r\n<p class=\"p1\">Select Main.storyboard in the navigator. Add the import statement to the top of this file:<b>@import NMAKit;</b> Name the outlet mapView, keep the other default options and then select Connect.</p>\r\n<p class=\"p1\"><b>3. Now an outlet to NMAMapView is set. The modified file should be as follows:</b></p>\r\n\r\n<pre>#import \"HelloMapViewController.h\"\r\n@import NMAKit;\r\n@interface HelloMapViewController ()\r\n@property (weak, nonatomic) IBOutlet NMAMapView *mapView;\r\n@end\r\n\r\n@implementation HelloMapViewController\r\n\r\n- (void)viewDidLoad\r\n{\r\n  [super viewDidLoad];\r\n}\r\n\r\n- (void)didReceiveMemoryWarning\r\n{\r\n  [super didReceiveMemoryWarning];\r\n}\r\n\r\n@end</pre>\r\n<p class=\"p1\"><b>4. Implement NMAMapView setup and lifecycle code by modifying the viewDidLoad method as shown:- </b></p>\r\n\r\n<pre>(void)viewDidLoad\r\n{\r\n  [super viewDidLoad];\r\n  //set geo center\r\n  NMAGeoCoordinates *geoCoordCenter =\r\n    [[NMAGeoCoordinates alloc] initWithLatitude:49.260327 longitude:-123.115025];\r\n  [self.mapView setGeoCenter:geoCoordCenter withAnimation:NMAMapAnimationNone];\r\n  self.mapView.copyrightLogoPosition = NMALayoutPositionBottomCenter;\r\n\r\n  //set zoom level\r\n  self.mapView.zoomLevel = 13.2;\r\n}</pre>\r\n<p class=\"p1\"><b>5. Add your HERE application credentials.</b></p>\r\n\r\n<ol class=\"ol1\">\r\n <li class=\"li1\">Open AppDelegate.m and import NMAKit by adding the following import statement to the top of the file.@import NMAKit;</li>\r\n <li class=\"li1\">Add the following in the didFinishLaunchingWithOptions method, replacing YOUR_APP_ID and YOUR_APP_CODE with the credentials that you received from <a href=\"http://developer.here.com/\">http://developer.here.com</a>.[NMAApplicationContext setAppId:@\"<a href=\"https://developer.here.com/documentation/ios-starter/dev_guide/topics/app-create-simple.html?insertAppId\">{YOUR_APP_ID}</a>\"  appCode:@\"<a href=\"https://developer.here.com/documentation/ios-starter/dev_guide/topics/app-create-simple.html?insertAppId\">{YOUR_APP_CODE}</a>\"];.</li>\r\n</ol>\r\n<p class=\"p1\"><b>Conclusion</b></p>\r\n<p class=\"p1\">Hope this article would help you understand the HereMap SDK integration in depth. There are various methods provided by the SDK to use its mapping and location changing properties. You can take help from the documentation provided by the platform itself, below are some references for its documentation.</p>\r\n<p class=\"p2\"><strong>References</strong></p>\r\n<p class=\"p3\"><a href=\"https://developer.here.com/documentation/android-starter/dev_guide/topics/maps.html\">HERE iOS SDK</a></p>\r\n<p class=\"p3\"><a href=\"https://github.com/heremaps/here-ios-sdk-examples\">HERE Map Github</a></p>\r\n<p class=\"p2\"><strong>Further Reading</strong></p>\r\n<p class=\"p3\"><a href=\"https://www.ipragmatech.com/how-to-build-website-quickly-platform-over-custom-development/\">How to build a website quickly using Platform over Custom development?</a></p>\r\n<p class=\"p3\"><a href=\"https://www.ipragmatech.com/?p=25062&amp;preview=true\">How Easy To Implement DZVideoPlayer in iOS App</a></p> <br /><center><hr/><em>Posted from my blog with <a href='https://www.ipragmatech.com'></a> : https://www.ipragmatech.com/how-easy-to-integrate-heremap-sdk-os-application/ </em><hr/></center>   ",
      "json_metadata": "{\"community\":\"steempress\",\"app\":\"steempress/1.4\",\"image\":[\"\"],\"tags\":[\"ipragmatech\"],\"original_link\":\"https://www.ipragmatech.com/how-easy-to-integrate-heremap-sdk-os-application/\"}",
      "parent_author": "",
      "parent_permlink": "ipragmatech",
      "permlink": "howeasytointegrateheremapsdkiniosappreadthis-pqm5kc9q00",
      "title": "How Easy To Integrate HereMap SDK  In iOS App, Read This!"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-07T09:03:24",
  "trx_id": "27c1341434604e566ab46a73043ba0a3eb71b2bd",
  "trx_in_block": 39,
  "virtual_op": 0
}
2019/01/05 01:40:15
authoripragmatech
permlinkeasilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
voterphusionphil
weight190 (1.90%)
Transaction InfoBlock #29176228/Trx 6254bc9a555fdde89a43a61af74fb836447b1f49
View Raw JSON Data
{
  "block": 29176228,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7",
      "voter": "phusionphil",
      "weight": 190
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-05T01:40:15",
  "trx_id": "6254bc9a555fdde89a43a61af74fb836447b1f49",
  "trx_in_block": 12,
  "virtual_op": 0
}
2019/01/05 01:39:36
authoripragmatech
permlinkeasilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
votersteempress-io
weight175 (1.75%)
Transaction InfoBlock #29176215/Trx 4a0ff2eb8f31653790a61b01f57a4478898634ad
View Raw JSON Data
{
  "block": 29176215,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7",
      "voter": "steempress-io",
      "weight": 175
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-05T01:39:36",
  "trx_id": "4a0ff2eb8f31653790a61b01f57a4478898634ad",
  "trx_in_block": 38,
  "virtual_op": 0
}
2019/01/05 01:39:30
authoripragmatech
permlinkeasilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
votersteempress
weight175 (1.75%)
Transaction InfoBlock #29176213/Trx b5b41bd556b11172b498eb5ebb507f9e800148f2
View Raw JSON Data
{
  "block": 29176213,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7",
      "voter": "steempress",
      "weight": 175
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-05T01:39:30",
  "trx_id": "b5b41bd556b11172b498eb5ebb507f9e800148f2",
  "trx_in_block": 2,
  "virtual_op": 0
}
2019/01/04 17:32:27
authoripragmatech
permlinkeasilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
votermagpielover
weight10000 (100.00%)
Transaction InfoBlock #29166488/Trx af6832dbb1f4d6d51e4909e610253aa0166cb773
View Raw JSON Data
{
  "block": 29166488,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7",
      "voter": "magpielover",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-04T17:32:27",
  "trx_id": "af6832dbb1f4d6d51e4909e610253aa0166cb773",
  "trx_in_block": 19,
  "virtual_op": 0
}
2019/01/04 17:31:57
authoripragmatech
permlinkeasilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
voterfilipino
weight1000 (10.00%)
Transaction InfoBlock #29166478/Trx b9fd3aaf5aa3a498b2e198bae96e2a97efd35caa
View Raw JSON Data
{
  "block": 29166478,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7",
      "voter": "filipino",
      "weight": 1000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-04T17:31:57",
  "trx_id": "b9fd3aaf5aa3a498b2e198bae96e2a97efd35caa",
  "trx_in_block": 1,
  "virtual_op": 0
}
2019/01/04 16:57:09
authoripragmatech
permlinkeasilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
votermicrobot
weight500 (5.00%)
Transaction InfoBlock #29165782/Trx 6a749e0d58115c33a0ab17182ce21b4f9b1a3709
View Raw JSON Data
{
  "block": 29165782,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7",
      "voter": "microbot",
      "weight": 500
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-04T16:57:09",
  "trx_id": "6a749e0d58115c33a0ab17182ce21b4f9b1a3709",
  "trx_in_block": 4,
  "virtual_op": 0
}
2019/01/04 16:55:48
authoripragmatech
permlinkeasilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
voteripragmatech
weight10000 (100.00%)
Transaction InfoBlock #29165755/Trx 71342412eb365179719f105e0d0d931557e77af9
View Raw JSON Data
{
  "block": 29165755,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7",
      "voter": "ipragmatech",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-04T16:55:48",
  "trx_id": "71342412eb365179719f105e0d0d931557e77af9",
  "trx_in_block": 22,
  "virtual_op": 0
}
2019/01/04 16:55:48
allow curation rewardstrue
allow votestrue
authoripragmatech
extensions[[0,{"beneficiaries":[{"account":"steempress","weight":1500}]}]]
max accepted payout1000000.000 SBD
percent steem dollars10000
permlinkeasilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
Transaction InfoBlock #29165755/Trx 71342412eb365179719f105e0d0d931557e77af9
View Raw JSON Data
{
  "block": 29165755,
  "op": [
    "comment_options",
    {
      "allow_curation_rewards": true,
      "allow_votes": true,
      "author": "ipragmatech",
      "extensions": [
        [
          0,
          {
            "beneficiaries": [
              {
                "account": "steempress",
                "weight": 1500
              }
            ]
          }
        ]
      ],
      "max_accepted_payout": "1000000.000 SBD",
      "percent_steem_dollars": 10000,
      "permlink": "easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-04T16:55:48",
  "trx_id": "71342412eb365179719f105e0d0d931557e77af9",
  "trx_in_block": 22,
  "virtual_op": 0
}
2019/01/04 16:55:48
authoripragmatech
body<center>http://www.ipragmatech.com/wp-content/uploads/2018/12/puppeteer-feature-image.png</center> <br/>Recently we were working on a project for Lifesherpa, a behavioral training app. They use a third party service which does not provide an extensive enough API to start some background jobs and get their status. This work needs to be done at a regular schedule. So, we needed to find a solution which would start the job automatically. It should also send email notifications to make it convenient to see the status of the job. So, we looked into various browser automation tools that are available. Since we use Firebase Functions to create APIs, the solution has to be compatible with Firebase. There are many options available for Node.js but we finally settled with Puppeteer as it is supported by Google. Firebase Functions have added support for running Headless Chrome with Node 8 engine. So, there are no compatibility issues. <h2>Introduction to Puppeteer</h2> Puppeteer is a Node.js library by Google. It allows you to programatically control Google Chrome or Chromium to interact with websites. You can do many things with it such as web scraping, take screenshots, generate PDFs, create UI tests, automate form submission and much more. Puppeteer uses a special version of Chrome called Headless Chrome. The only thing different from the regular version is that you can use it without showing the UI. This makes it easy to run Chrome on devices which don't have a display. You can write your automation code in Puppeteer once and deploy it on your server to run without user interaction. In this tutorial, we will go through the basics of using Puppeteer to monitor a website and send email notifications. Then, we will deploy it on Firebase Functions. Finally, we can call its API URL using cron jobs as required. <img class="alignnone wp-image-25253 size-full" src="http://www.ipragmatech.com/wp-content/uploads/2018/12/puppeteer-infographic-e1544348603872.jpg" alt="puppeteer-infographic" width="768" height="1042" /><br/> For testing, I have setup a demo site which has two pages: <ol> <li>Login page: Enter username and password to login</li> <li>Dashboard page: There is a 'Start Process' button. Clicking it will randomly display a success or failure response after a short delay. This is for simulating an API response.</li> </ol> <img class="alignnone size-full wp-image-25247" src="http://www.ipragmatech.com/wp-content/uploads/2018/12/puppeteer-live-preview.gif" alt="Puppeteer Live Preview" width="600" height="343" /><br/> You can get the code used in this tutorial in the GitHub repository <a href="https://github.com/ipragmatech/puppeteer-tutorial" target="_blank" rel="noopener">here</a>. <strong>Steps:</strong> <h4>Step 1: Check Dependencies:</h4> First of all ensure that you are running Node 8 in your local machine. If not, then upgrade it. Also, update firebase-functions and firebase-admin packages to the latest version. <pre class="western">npm install firebase-functions@latest firebase-admin@latest –save </pre> To use Puppeteer on Firebase you need to enable Node 8 for your function. To do so, go to package.json file and add following: <pre class="western">"engines": { "node": "8" }</pre> Install puppeteer and nodemailer <pre class="western">npm install puppeteer nodemailer</pre> It will automatically download the latest version of Chromium which is compatible with Puppeteer. Thus, no compatibility issue can arrise. Also, we will use nodemailer to send email notifications for errors. <h4>Step 2: Create monitor function</h4> Create index.js file with the following code. It might look complex but it will be easy to understand with the explanation given below. <pre class="western">const functions = require('firebase-functions'); const admin = require('firebase-admin'); const puppeteer = require('puppeteer'); const nodemailer = require('nodemailer'); admin.initializeApp(); const config = { navigationTimeout: 40000, login: { url: "https://ipragmatech.github.io/puppeteer-tutorial/public/", targets: { username: "#username", password: "#password", submit: "#submit" }, form: { username: "abcdefg", password: "123456" } }, dashboard: { targets: { startProcess: "#startProcess", notification: ".alert" } }, //Replace with your smtp server details smtp: { host: "https://abcdefg.com", port: 465, secure: true, user: "user123", pass: "pass123", from: "[email protected]", to: "[email protected]" } } exports.monitor = functions.runWith({ memory: '512MB' }).https.onRequest(async (req, res) =&gt; { try { const browser = await puppeteer.launch({ args: ['--no-sandbox'], headless: true }).catch(customError("Failed to start Chrome")); const page = await browser.newPage() .catch(customError("Failed to open new page")); await page.goto(config.login.url) .catch(customError("Failed to open login page")); console.log("Opened login page: " + config.login.url); await page.type(config.login.targets.username, config.login.form.username) .catch(customError("Failed to type username. Page did not load completely or the selector for username has changed.")); await page.type(config.login.targets.password, config.login.form.password) .catch(customError("Failed to type password. Page did not load completely or the selector for password has changed.")); await Promise.all([ page.waitForNavigation(config.navigationTimeout, { waitUntil: "networkidle0" }), page.click(config.login.targets.submit) ]).catch(customError("Failed to login or failed to redirect after login")); console.log("Logged in successfully"); await page.click(config.dashboard.targets.startProcess) .catch(customError("Failed to click Start Process button. The selector has changed or page did not load fully")); await page.waitForSelector(config.dashboard.targets.notification) .catch(customError("Notification not received or selector for notification has changed")); const result = await page.evaluate((config) =&gt; document.querySelector(config.dashboard.targets.notification).innerText, config) .catch(customError("Failed to extract message from page")); console.log("Result: " + result); await browser.close() .catch(customError("An issue occured while trying to close the browser.")); console.log("Closed browser window"); if (result.search("Failed") !== -1) { throw { result: "Process status result shows that it did not complete successfully", error: { message: result } }; } return res.send({ result: "No errors found" }); } catch (customError) { console.error("An error occured."); console.error(customError); await sendEmail(customError); return res.status(500).send(customError); } }); // Create custom error object so that only one try/catch is needed to handle all errors function customError(result) { return (error) =&gt; { if (!error) { error = {}; } else { error = { message: error.message, stack: error.stack } } throw { result, error }; } } async function sendEmail(response) { try { const reportDate = new Date().toUTCString(); const error = JSON.stringify(response.error, null, 2); const html = `&lt;body&gt; &lt;h3&gt;Error Date ${reportDate}&lt;/h3&gt; &lt;p&gt;Info: ${response.result}&lt;/p&gt; &lt;pre&gt;${error}&lt;/pre&gt; &lt;/body&gt;`; console.log("Generated HTML"); console.log(html); const { from, to, host, port, secure, user, pass } = config.smtp; const transporter = nodemailer.createTransport({ host, port, secure, auth: { user, pass } }); await transporter.sendMail({ from, to, subject: `Monitor Status: Error found`, html }); console.log("Email sent successfully"); } catch (error) { console.error("failed to send email"); console.error(error); } }</pre> Explanation: <div style="margin-left: 20px;"> <h4>1. Prepare Configuration</h4> &nbsp; <pre class="western">const config = { login: { url: "https://ipragmatech.github.io/puppeteer-tutorial/public/", targets: { username: "#username", password: "#password", submit: "#submit" }, form: { username: "abcdefg", password: "123456" } }, dashboard: { targets: { startProcess: "#startProcess", notification: ".alert" } }, //Replace with your smtp server details smtp: { host: "https://abcdefg.com", port: 465, secure: true, user: "user123", pass: "pass123", from: "[email protected]", to: "[email protected]" } };</pre> config object contains details about selectors, form inputs and SMTP configuration for sending email. All this is saved in config to make it easy to edit them without looking into the code below. &nbsp; <pre class="western">exports.monitor = functions.runWith({ memory: '512MB' }).https.onRequest(async (req, res) =&gt; {</pre> We can increase the memory alloted to the function by specifying the memory in functions.runWith. Also, you can choose from 128MB, 256MB, 512MB, 1GB and 2GB. async means that this function uses the new async/await syntax. It allows using promises without .then() . Likewise, try/catch is used for error handling instead of .catch().It makes asynchronous code look like synchronous code. You can read more about async/await <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function" target="_blank" rel="noopener">here</a>. &nbsp; <pre class="western">// Create custom error object so that only one try/catch is needed to handle all errors function customError(result) { return (error) =&gt; { if (!error) { error = {}; } else { error = { message: error.message, stack: error.stack } } throw { result, error }; } }</pre> This is a helper function. It allows adding customised error messages to any error. So, instead of writing multiple nested try/catch for all promises, we can just create a custom error object, add our human readable error string and re-throw it. The catch block at the end will catch the error and send notifications with the custom message. Thus, making the code look clean and easy to understand. &nbsp; <pre class="western">try { const browser = await puppeteer.launch({ args: ['--no-sandbox'], headless: true }).catch(customError("Failed to start Chrome"));</pre> It is starts a browser instance. Configure two things here: <ol> <li>args: ['--no-sandbox'] – Disable Chromium’s sandbox because Firebase currently does not support running Headless Chrome with sandbox.</li> <li>headless: true – It's optional. This setting is true by default. But if it is set to false, Chromium will start with its GUI.  Thus, is helpful for debugging purposes.</li> </ol> &nbsp; <h4>2. Write automation code</h4> &nbsp; <pre class="western">const page = await browser.newPage() .catch(customError("Failed to open new page"));</pre> It opens a new tab in Chromium. &nbsp; <pre class="western">await page.goto(config.login.url) .catch(customError("Failed to open login page")); console.log("Opened login page: " + config.login.url);</pre> page.goto navigates the browser to a URL. &nbsp; <pre class="western">await page.type(config.login.targets.username, config.login.form.username) .catch(customError("Failed to type username. Page did not load completely or the selector for username has changed.")); await page.type(config.login.targets.password, config.login.form.password) .catch(customError("Failed to type password. Page did not load completely or the selector for password has changed."));</pre> page.type enters text into input boxes. This requires entering the CSS selector of the required element in page.type . It can fail when the input element is not rendered yet in the browser due to slow internet or the selector for the element has been changed by the website. &nbsp; <pre class="western">await Promise.all([ page.waitForNavigation(config.navigationTimeout, { waitUntil: "networkidle0" }), page.click(config.login.targets.submit) ]).catch(customError("Failed to login or failed to redirect after login")); console.log("Logged in successfully");</pre> page.click clicks on any HTML element. It can fail if the element does not render in time or the selector for the element has changed. page.waitForNavigation stops processing while the page is loading after a navigation event. It gives timeout error if the navigation does not complete in required time. Also, page.waitForNavigation needs to be added in a Promise.all with page.click if the click event starts any navigation event. &nbsp; <pre class="western">await page.click(config.dashboard.targets.startProcess) .catch(customError("Failed to click Start Process button. The selector has changed or page did not load fully")); await page.waitForSelector(config.dashboard.targets.notification) .catch(customError("Notification not received or selector for notification has changed"));</pre> After dashboard page loads, click "Start Process" button. Then we wait for the result of the process. To do so, page.waitForSelector is used. It halts the function till an element with the specified selector is created in the DOM. &nbsp; <pre class="western">const result = await page.evaluate((config) =&gt; document.querySelector(config.dashboard.targets.notification).innerText, config) .catch(customError("Failed to extract message from page")); console.log("Result: " + result);</pre> page.evaluate allows you to execute custom JavaScript on websites running in the browser. Use it for data scraping and analysing the data in a webpage. To use any variable from outside, pass the variable as argument to page.evaluation. This variable then becomes accessible from inside the browser. Then, store any value returned from the callback function into results. After the processing is complete, the notification element contains info regarding the success/failure of the process. We save the notification text in result. &nbsp; <pre class="western">await browser.close() .catch(customError("An issue occured while trying to close the browser.")); console.log("Closed browser window");</pre> browser.close stops the browser session. &nbsp; <pre class="western">if (result.search("Failed") !== -1) { throw { result: "Process status result shows that it did not complete successfully", error: { message: result } }; }</pre> If the result of processing contains the word "Failed", then throw an error to send notification for it. <h4>3. Send email notifications</h4> &nbsp; <pre class="western">async function sendEmail(response) { const reportDate = new Date().toUTCString(); const error = JSON.stringify(response.error, null, 2); const html = `&lt;body&gt; &lt;h3&gt;Error Date ${reportDate}&lt;/h3&gt; &lt;p&gt;Info: ${response.result}&lt;/p&gt; &lt;pre&gt;${error}&lt;/pre&gt; &lt;/body&gt;`;</pre> Create HTML for the email with date and error details. &nbsp; <pre class="western">const { from, to, host, port, secure, user, pass } = config.smtp; const transporter = nodemailer.createTransport({ host, port, secure, auth: { user, pass } });</pre> Use SMTP details to create a Nodemailer transporter object. &nbsp; <pre class="western">await transporter.sendMail({ from, to, subject: `Monitor Status: Error found`, html });</pre> As you can guess, sendMail sends the email to the specified recipients. You can specify multiple recipients by separating them using commas. These are just the basics of what you can do with Nodemailer. To know about more features, go to its documentation <a href="https://nodemailer.com/about/" target="_blank" rel="noopener">here</a>. &nbsp; </div> <h4>Step 3: Start Firebase local emulator:</h4> &nbsp; To test the monitor function, open the project directory in terminal and type <pre class="western">firebase serve --only functions</pre> It will provide a local URL for the function. Go to the URL in your web browser and observe the logs in the terminal while the process finishes. If any error occurs, you will receive an email notification for it. <img class="alignnone size-full wp-image-25242" src="http://www.ipragmatech.com/wp-content/uploads/2018/12/puppeteer-terminal-preview.png" alt="" width="770" height="505" /><br/> &nbsp; Set "headless: false" in puppeteer.launch() function call. Now start the monitor function again. This time, Puppeteer will start the GUI of Chromium and show the automation process in realtime. So, if you face any issues in headless mode, you can debug them by using visual feedback from the GUI. <h4>Step 4: Deploy to Firebase</h4> &nbsp; Finally, to deploy to Firebase, run <pre class="western">firebase deploy --only functions:monitor</pre> After you get its API endpoint, you can use a cron job service such as cron-job.org, easycron etc. to hit this endpoint at scheduled times. You will get email notifications automatically if there is any issue in the results. <h2>Conclusion</h2> Thus Puppeteer is a very easy to use library to automate various tasks with Chrome. You can combine it with testing libraries like mocha and jest and create extensive UI tests. Or you can write a scrapper which goes through all pages in a website and converts them into PDFs. Or you can automate things in websites which don’t provide any API. The possibilities are endless. Start experimenting and see what it can do for you. <h2>References</h2> <ul> <li><a href="https://pptr.dev/" target="_blank" rel="noopener">Puppeteer Documentation</a></li> <li><a href="https://nodemailer.com/about/" target="_blank" rel="noopener">Nodemailer Documentation </a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function" target="_blank" rel="noopener">JavaScript async/await syntax reference</a></li> </ul> <h2>Further reading</h2> <ul> <li><a href="https://www.ipragmatech.com/contacts-app-firebase-angularjs/">Creating a basic Contacts app with Firebase and AngularJS</a></li> <li><a href="https://www.ipragmatech.com/test-cases-postman-api-testing/">The ultimate guide to create test cases for postman for API testing</a></li> <li><a href="https://www.ipragmatech.com/contacts-app-firebase-angularjs/">Five steps to build a basic contacts app using Firebase and AngularJS</a></li> </ul> <br /><center><hr/><em>Posted from my blog with <a href='https://www.ipragmatech.com'></a> : https://www.ipragmatech.com/puppeteer-firebase-monitor-websites/ </em><hr/></center>
json metadata{"community":"steempress","app":"steempress/1.4","image":[""],"tags":["ipragmatech"],"original_link":"https://www.ipragmatech.com/puppeteer-firebase-monitor-websites/"}
parent author
parent permlinkipragmatech
permlinkeasilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7
titleEasily Automate Website Monitoring with Puppeteer and Firebase
Transaction InfoBlock #29165755/Trx 71342412eb365179719f105e0d0d931557e77af9
View Raw JSON Data
{
  "block": 29165755,
  "op": [
    "comment",
    {
      "author": "ipragmatech",
      "body": "<center>http://www.ipragmatech.com/wp-content/uploads/2018/12/puppeteer-feature-image.png</center> <br/>Recently we were working on a project for Lifesherpa, a behavioral training app. They use a third party service which does not provide an extensive enough API to start some background jobs and get their status. This work needs to be done at a regular schedule. So, we needed to find a solution which would start the job automatically. It should also send email notifications to make it convenient to see the status of the job. So, we looked into various browser automation tools that are available. Since we use Firebase Functions to create APIs, the solution has to be compatible with Firebase. There are many options available for Node.js but we finally settled with Puppeteer as it is supported by Google. Firebase Functions have added support for running Headless Chrome with Node 8 engine. So, there are no compatibility issues.\r\n<h2>Introduction to Puppeteer</h2>\r\nPuppeteer is a Node.js library by Google. It allows you to programatically control Google Chrome or Chromium to interact with websites. You can do many things with it such as web scraping, take screenshots, generate PDFs, create UI tests, automate form submission and much more. Puppeteer uses a special version of Chrome called Headless Chrome. The only thing different from the regular version is that you can use it without showing the UI. This makes it easy to run Chrome on devices which don't have a display. You can write your automation code in Puppeteer once and deploy it on your server to run without user interaction.\r\nIn this tutorial, we will go through the basics of using Puppeteer to monitor a website and send email notifications. Then, we will deploy it on Firebase Functions. Finally, we can call its API URL using cron jobs as required.\r\n\r\n<img class=\"alignnone wp-image-25253 size-full\" src=\"http://www.ipragmatech.com/wp-content/uploads/2018/12/puppeteer-infographic-e1544348603872.jpg\" alt=\"puppeteer-infographic\" width=\"768\" height=\"1042\" /><br/>\r\n\r\nFor testing, I have setup a demo site which has two pages:\r\n<ol>\r\n <li>Login page: Enter username and password to login</li>\r\n <li>Dashboard page: There is a 'Start Process' button. Clicking it will randomly display a success or failure response after a short delay. This is for simulating an API response.</li>\r\n</ol>\r\n<img class=\"alignnone size-full wp-image-25247\" src=\"http://www.ipragmatech.com/wp-content/uploads/2018/12/puppeteer-live-preview.gif\" alt=\"Puppeteer Live Preview\" width=\"600\" height=\"343\" /><br/>\r\n\r\nYou can get the code used in this tutorial in the GitHub repository <a href=\"https://github.com/ipragmatech/puppeteer-tutorial\" target=\"_blank\" rel=\"noopener\">here</a>.\r\n\r\n<strong>Steps:</strong>\r\n<h4>Step 1: Check Dependencies:</h4>\r\nFirst of all ensure that you are running Node 8 in your local machine. If not, then upgrade it.\r\nAlso, update firebase-functions and firebase-admin packages to the latest version.\r\n<pre class=\"western\">npm install firebase-functions@latest firebase-admin@latest –save\r\n</pre>\r\nTo use Puppeteer on Firebase you need to enable Node 8 for your function. To do so, go to package.json file and add following:\r\n<pre class=\"western\">\"engines\": {\r\n    \"node\": \"8\"\r\n}</pre>\r\nInstall puppeteer and nodemailer\r\n<pre class=\"western\">npm install puppeteer nodemailer</pre>\r\nIt will automatically download the latest version of Chromium which is compatible with Puppeteer. Thus, no compatibility issue can arrise.\r\n\r\nAlso, we will use nodemailer to send email notifications for errors.\r\n<h4>Step 2: Create monitor function</h4>\r\nCreate index.js file with the following code. It might look complex but it will be easy to understand with the explanation given below.\r\n<pre class=\"western\">const functions = require('firebase-functions');\r\nconst admin = require('firebase-admin');\r\nconst puppeteer = require('puppeteer');\r\nconst nodemailer = require('nodemailer');\r\n\r\nadmin.initializeApp();\r\n\r\nconst config = {\r\nnavigationTimeout: 40000,\r\nlogin: {\r\nurl: \"https://ipragmatech.github.io/puppeteer-tutorial/public/\",\r\ntargets: {\r\nusername: \"#username\",\r\npassword: \"#password\",\r\nsubmit: \"#submit\"\r\n},\r\nform: {\r\nusername: \"abcdefg\",\r\npassword: \"123456\"\r\n}\r\n},\r\ndashboard: {\r\ntargets: {\r\nstartProcess: \"#startProcess\",\r\nnotification: \".alert\"\r\n}\r\n},\r\n//Replace with your smtp server details\r\nsmtp: {\r\nhost: \"https://abcdefg.com\",\r\nport: 465,\r\nsecure: true,\r\nuser: \"user123\",\r\npass: \"pass123\",\r\nfrom: \"[email protected]\",\r\nto: \"[email protected]\"\r\n}\r\n}\r\n\r\nexports.monitor = functions.runWith({ memory: '512MB' }).https.onRequest(async (req, res) =&gt; {\r\n\r\ntry {\r\nconst browser = await puppeteer.launch({\r\nargs: ['--no-sandbox'],\r\nheadless: true\r\n}).catch(customError(\"Failed to start Chrome\"));\r\n\r\nconst page = await browser.newPage()\r\n.catch(customError(\"Failed to open new page\"));\r\n\r\nawait page.goto(config.login.url)\r\n.catch(customError(\"Failed to open login page\"));\r\n\r\nconsole.log(\"Opened login page: \" + config.login.url);\r\n\r\nawait page.type(config.login.targets.username, config.login.form.username)\r\n.catch(customError(\"Failed to type username. Page did not load completely or the selector for username has changed.\"));\r\n\r\nawait page.type(config.login.targets.password, config.login.form.password)\r\n.catch(customError(\"Failed to type password. Page did not load completely or the selector for password has changed.\"));\r\n\r\nawait Promise.all([\r\npage.waitForNavigation(config.navigationTimeout, {\r\nwaitUntil: \"networkidle0\"\r\n}),\r\npage.click(config.login.targets.submit)\r\n]).catch(customError(\"Failed to login or failed to redirect after login\"));\r\n\r\nconsole.log(\"Logged in successfully\");\r\n\r\nawait page.click(config.dashboard.targets.startProcess)\r\n.catch(customError(\"Failed to click Start Process button. The selector has changed or page did not load fully\"));\r\nawait page.waitForSelector(config.dashboard.targets.notification)\r\n.catch(customError(\"Notification not received or selector for notification has changed\"));\r\n\r\nconst result = await page.evaluate((config) =&gt; document.querySelector(config.dashboard.targets.notification).innerText, config)\r\n.catch(customError(\"Failed to extract message from page\"));\r\n\r\nconsole.log(\"Result: \" + result);\r\nawait browser.close()\r\n.catch(customError(\"An issue occured while trying to close the browser.\"));\r\nconsole.log(\"Closed browser window\");\r\n\r\nif (result.search(\"Failed\") !== -1) {\r\nthrow {\r\nresult: \"Process status result shows that it did not complete successfully\",\r\nerror: {\r\nmessage: result\r\n}\r\n};\r\n}\r\n\r\nreturn res.send({\r\nresult: \"No errors found\"\r\n});\r\n\r\n} catch (customError) {\r\nconsole.error(\"An error occured.\");\r\nconsole.error(customError);\r\nawait sendEmail(customError);\r\nreturn res.status(500).send(customError);\r\n}\r\n\r\n});\r\n\r\n// Create custom error object so that only one try/catch is needed to handle all errors\r\nfunction customError(result) {\r\nreturn (error) =&gt; {\r\nif (!error) {\r\nerror = {};\r\n} else {\r\nerror = {\r\nmessage: error.message,\r\nstack: error.stack\r\n}\r\n}\r\nthrow { result, error };\r\n}\r\n}\r\n\r\nasync function sendEmail(response) {\r\n\r\ntry {\r\nconst reportDate = new Date().toUTCString();\r\nconst error = JSON.stringify(response.error, null, 2);\r\nconst html = `&lt;body&gt;\r\n&lt;h3&gt;Error Date ${reportDate}&lt;/h3&gt;\r\n&lt;p&gt;Info: ${response.result}&lt;/p&gt;\r\n&lt;pre&gt;${error}&lt;/pre&gt;\r\n&lt;/body&gt;`;\r\n\r\nconsole.log(\"Generated HTML\");\r\nconsole.log(html);\r\n\r\nconst { from, to, host, port, secure, user, pass } = config.smtp;\r\nconst transporter = nodemailer.createTransport({\r\nhost,\r\nport,\r\nsecure,\r\nauth: {\r\nuser,\r\npass\r\n}\r\n});\r\nawait transporter.sendMail({\r\nfrom,\r\nto,\r\nsubject: `Monitor Status: Error found`,\r\nhtml\r\n});\r\nconsole.log(\"Email sent successfully\");\r\n\r\n} catch (error) {\r\nconsole.error(\"failed to send email\");\r\nconsole.error(error);\r\n}\r\n}</pre>\r\nExplanation:\r\n<div style=\"margin-left: 20px;\">\r\n<h4>1. Prepare Configuration</h4>\r\n&nbsp;\r\n<pre class=\"western\">const config = {\r\nlogin: {\r\nurl: \"https://ipragmatech.github.io/puppeteer-tutorial/public/\",\r\ntargets: {\r\nusername: \"#username\",\r\npassword: \"#password\",\r\nsubmit: \"#submit\"\r\n},\r\nform: {\r\nusername: \"abcdefg\",\r\npassword: \"123456\"\r\n}\r\n},\r\ndashboard: {\r\ntargets: {\r\nstartProcess: \"#startProcess\",\r\nnotification: \".alert\"\r\n}\r\n},\r\n//Replace with your smtp server details\r\nsmtp: {\r\nhost: \"https://abcdefg.com\",\r\nport: 465,\r\nsecure: true,\r\nuser: \"user123\",\r\npass: \"pass123\",\r\nfrom: \"[email protected]\",\r\nto: \"[email protected]\"\r\n}\r\n};</pre>\r\nconfig object contains details about selectors, form inputs and SMTP configuration for sending email. All this is saved in config to make it easy to edit them without looking into the code below.\r\n\r\n&nbsp;\r\n<pre class=\"western\">exports.monitor = functions.runWith({ memory: '512MB' }).https.onRequest(async (req, res) =&gt; {</pre>\r\nWe can increase the memory alloted to the function by specifying the memory in functions.runWith. Also, you can choose from 128MB, 256MB, 512MB, 1GB and 2GB.\r\n\r\nasync means that this function uses the new async/await syntax. It allows using promises without .then() . Likewise, try/catch is used for error handling instead of .catch().It makes asynchronous code look like synchronous code. You can read more about async/await <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function\" target=\"_blank\" rel=\"noopener\">here</a>.\r\n\r\n&nbsp;\r\n<pre class=\"western\">// Create custom error object so that only one try/catch is needed to handle all errors\r\nfunction customError(result) {\r\nreturn (error) =&gt; {\r\nif (!error) {\r\nerror = {};\r\n} else {\r\nerror = {\r\nmessage: error.message,\r\nstack: error.stack\r\n}\r\n}\r\nthrow { result, error };\r\n}\r\n}</pre>\r\nThis is a helper function. It allows adding customised error messages to any error. So, instead of writing multiple nested try/catch for all promises, we can just create a custom error object, add our human readable error string and re-throw it. The catch block at the end will catch the error and send notifications with the custom message. Thus, making the code look clean and easy to understand.\r\n\r\n&nbsp;\r\n<pre class=\"western\">try {\r\nconst browser = await puppeteer.launch({\r\nargs: ['--no-sandbox'],\r\nheadless: true\r\n}).catch(customError(\"Failed to start Chrome\"));</pre>\r\nIt is starts a browser instance. Configure two things here:\r\n<ol>\r\n <li>args: ['--no-sandbox'] – Disable Chromium’s sandbox because Firebase currently does not support running Headless Chrome with sandbox.</li>\r\n <li>headless: true – It's optional. This setting is true by default. But if it is set to false, Chromium will start with its GUI.  Thus, is helpful for debugging purposes.</li>\r\n</ol>\r\n&nbsp;\r\n<h4>2. Write automation code</h4>\r\n&nbsp;\r\n<pre class=\"western\">const page = await browser.newPage()\r\n.catch(customError(\"Failed to open new page\"));</pre>\r\nIt opens a new tab in Chromium.\r\n\r\n&nbsp;\r\n<pre class=\"western\">await page.goto(config.login.url)\r\n.catch(customError(\"Failed to open login page\"));\r\n\r\nconsole.log(\"Opened login page: \" + config.login.url);</pre>\r\npage.goto navigates the browser to a URL.\r\n\r\n&nbsp;\r\n<pre class=\"western\">await page.type(config.login.targets.username, config.login.form.username)\r\n.catch(customError(\"Failed to type username. Page did not load completely or the selector for username has changed.\"));\r\n\r\nawait page.type(config.login.targets.password, config.login.form.password)\r\n.catch(customError(\"Failed to type password. Page did not load completely or the selector for password has changed.\"));</pre>\r\npage.type enters text into input boxes. This requires entering the CSS selector of the required element in page.type . It can fail when the input element is not rendered yet in the browser due to slow internet or the selector for the element has been changed by the website.\r\n\r\n&nbsp;\r\n<pre class=\"western\">await Promise.all([\r\npage.waitForNavigation(config.navigationTimeout, {\r\nwaitUntil: \"networkidle0\"\r\n}),\r\npage.click(config.login.targets.submit)\r\n]).catch(customError(\"Failed to login or failed to redirect after login\"));\r\n\r\nconsole.log(\"Logged in successfully\");</pre>\r\npage.click clicks on any HTML element. It can fail if the element does not render in time or the selector for the element has changed.\r\n\r\npage.waitForNavigation stops processing while the page is loading after a navigation event. It gives timeout error if the navigation does not complete in required time.\r\n\r\nAlso, page.waitForNavigation needs to be added in a Promise.all with page.click if the click event starts any navigation event.\r\n\r\n&nbsp;\r\n<pre class=\"western\">await page.click(config.dashboard.targets.startProcess)\r\n.catch(customError(\"Failed to click Start Process button. The selector has changed or page did not load fully\"));\r\nawait page.waitForSelector(config.dashboard.targets.notification)\r\n.catch(customError(\"Notification not received or selector for notification has changed\"));</pre>\r\nAfter dashboard page loads, click \"Start Process\" button. Then we wait for the result of the process. To do so, page.waitForSelector is used. It halts the function till an element with the specified selector is created in the DOM.\r\n\r\n&nbsp;\r\n<pre class=\"western\">const result = await page.evaluate((config) =&gt; document.querySelector(config.dashboard.targets.notification).innerText, config)\r\n.catch(customError(\"Failed to extract message from page\"));\r\n\r\nconsole.log(\"Result: \" + result);</pre>\r\npage.evaluate allows you to execute custom JavaScript on websites running in the browser. Use it for data scraping and analysing the data in a webpage. To use any variable from outside, pass the variable as argument to page.evaluation. This variable then becomes accessible from inside the browser. Then, store any value returned from the callback function into results.\r\n\r\nAfter the processing is complete, the notification element contains info regarding the success/failure of the process. We save the notification text in result.\r\n\r\n&nbsp;\r\n<pre class=\"western\">await browser.close()\r\n.catch(customError(\"An issue occured while trying to close the browser.\"));\r\nconsole.log(\"Closed browser window\");</pre>\r\nbrowser.close stops the browser session.\r\n\r\n&nbsp;\r\n<pre class=\"western\">if (result.search(\"Failed\") !== -1) {\r\nthrow {\r\nresult: \"Process status result shows that it did not complete successfully\",\r\nerror: {\r\nmessage: result\r\n}\r\n};\r\n}</pre>\r\nIf the result of processing contains the word \"Failed\", then throw an error to send notification for it.\r\n<h4>3. Send email notifications</h4>\r\n&nbsp;\r\n<pre class=\"western\">async function sendEmail(response) {\r\nconst reportDate = new Date().toUTCString();\r\nconst error = JSON.stringify(response.error, null, 2);\r\nconst html = `&lt;body&gt;\r\n&lt;h3&gt;Error Date ${reportDate}&lt;/h3&gt;\r\n&lt;p&gt;Info: ${response.result}&lt;/p&gt;\r\n&lt;pre&gt;${error}&lt;/pre&gt;\r\n&lt;/body&gt;`;</pre>\r\nCreate HTML for the email with date and error details.\r\n\r\n&nbsp;\r\n<pre class=\"western\">const { from, to, host, port, secure, user, pass } = config.smtp;\r\nconst transporter = nodemailer.createTransport({\r\nhost,\r\nport,\r\nsecure,\r\nauth: {\r\nuser,\r\npass\r\n}\r\n});</pre>\r\nUse SMTP details to create a Nodemailer transporter object.\r\n\r\n&nbsp;\r\n<pre class=\"western\">await transporter.sendMail({\r\nfrom,\r\nto,\r\nsubject: `Monitor Status: Error found`,\r\nhtml\r\n});</pre>\r\nAs you can guess, sendMail sends the email to the specified recipients. You can specify multiple recipients by separating them using commas. These are just the basics of what you can do with Nodemailer. To know about more features, go to its documentation <a href=\"https://nodemailer.com/about/\" target=\"_blank\" rel=\"noopener\">here</a>.\r\n\r\n&nbsp;\r\n\r\n</div>\r\n<h4>Step 3: Start Firebase local emulator:</h4>\r\n&nbsp;\r\n\r\nTo test the monitor function, open the project directory in terminal and type\r\n<pre class=\"western\">firebase serve --only functions</pre>\r\nIt will provide a local URL for the function. Go to the URL in your web browser and observe the logs in the terminal while the process finishes. If any error occurs, you will receive an email notification for it.\r\n\r\n<img class=\"alignnone size-full wp-image-25242\" src=\"http://www.ipragmatech.com/wp-content/uploads/2018/12/puppeteer-terminal-preview.png\" alt=\"\" width=\"770\" height=\"505\" /><br/>\r\n\r\n&nbsp;\r\n\r\nSet \"headless: false\" in puppeteer.launch() function call. Now start the monitor function again. This time, Puppeteer will start the GUI of Chromium and show the automation process in realtime. So, if you face any issues in headless mode, you can debug them by using visual feedback from the GUI.\r\n<h4>Step 4: Deploy to Firebase</h4>\r\n&nbsp;\r\n\r\nFinally, to deploy to Firebase, run\r\n<pre class=\"western\">firebase deploy --only functions:monitor</pre>\r\nAfter you get its API endpoint, you can use a cron job service such as cron-job.org, easycron etc. to hit this endpoint at scheduled times. You will get email notifications automatically if there is any issue in the results.\r\n<h2>Conclusion</h2>\r\nThus Puppeteer is a very easy to use library to automate various tasks with Chrome. You can combine it with testing libraries like mocha and jest and create extensive UI tests. Or you can write a scrapper which goes through all pages in a website and converts them into PDFs. Or you can automate things in websites which don’t provide any API. The possibilities are endless. Start experimenting and see what it can do for you.\r\n<h2>References</h2>\r\n<ul>\r\n <li><a href=\"https://pptr.dev/\" target=\"_blank\" rel=\"noopener\">Puppeteer Documentation</a></li>\r\n <li><a href=\"https://nodemailer.com/about/\" target=\"_blank\" rel=\"noopener\">Nodemailer Documentation\r\n</a></li>\r\n <li><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function\" target=\"_blank\" rel=\"noopener\">JavaScript async/await syntax reference</a></li>\r\n</ul>\r\n<h2>Further reading</h2>\r\n<ul>\r\n <li><a href=\"https://www.ipragmatech.com/contacts-app-firebase-angularjs/\">Creating a basic Contacts app with Firebase and AngularJS</a></li>\r\n <li><a href=\"https://www.ipragmatech.com/test-cases-postman-api-testing/\">The ultimate guide to create test cases for postman for API testing</a></li>\r\n <li><a href=\"https://www.ipragmatech.com/contacts-app-firebase-angularjs/\">Five steps to build a basic contacts app using Firebase and AngularJS</a></li>\r\n</ul> <br /><center><hr/><em>Posted from my blog with <a href='https://www.ipragmatech.com'></a> : https://www.ipragmatech.com/puppeteer-firebase-monitor-websites/ </em><hr/></center>   ",
      "json_metadata": "{\"community\":\"steempress\",\"app\":\"steempress/1.4\",\"image\":[\"\"],\"tags\":[\"ipragmatech\"],\"original_link\":\"https://www.ipragmatech.com/puppeteer-firebase-monitor-websites/\"}",
      "parent_author": "",
      "parent_permlink": "ipragmatech",
      "permlink": "easilyautomatewebsitemonitoringwithpuppeteerandfirebase-y7v1t6nvg7",
      "title": "Easily Automate Website Monitoring with Puppeteer and Firebase"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-04T16:55:48",
  "trx_id": "71342412eb365179719f105e0d0d931557e77af9",
  "trx_in_block": 22,
  "virtual_op": 0
}
2018/12/31 11:10:09
authoripragmatech
permlinkchooseyourimageloaderaccordingtoyourandroidappsmartly-kpo9fe11uf
votersteempress-io
weight175 (1.75%)
Transaction InfoBlock #29043808/Trx 8fc75ec6d1826dcbac3c6701b4753c5af06b0d26
View Raw JSON Data
{
  "block": 29043808,
  "op": [
    "vote",
    {
      "author": "ipragmatech",
      "permlink": "chooseyourimageloaderaccordingtoyourandroidappsmartly-kpo9fe11uf",
      "voter": "steempress-io",
      "weight": 175
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-12-31T11:10:09",
  "trx_id": "8fc75ec6d1826dcbac3c6701b4753c5af06b0d26",
  "trx_in_block": 0,
  "virtual_op": 0
}

Account Metadata

POSTING JSON METADATA
profile{"profile_image":"https://cdn.steemitimages.com/DQmXG4wKH4Aq7y5Ypimdj7zYdFvqCpvFdeuVWmPoUgzrQgf/IMG_2306.jpg","name":"Kapil Jain","about":"I love to travel and meeting people with different culture.","location":"Delhi, India","website":"https://www.ipragmatech.com","cover_image":"https://cdn.steemitimages.com/DQmfX8FptYvkJiGCafeg4TXJrp9r9PLsjn3uNyP9ocsDeWs/IMG_20180609_165708452_HDR-EFFECTS.jpg"}
JSON METADATA
profile{"profile_image":"https://cdn.steemitimages.com/DQmXG4wKH4Aq7y5Ypimdj7zYdFvqCpvFdeuVWmPoUgzrQgf/IMG_2306.jpg","name":"Kapil Jain","about":"I love to travel and meeting people with different culture.","location":"Delhi, India","website":"https://www.ipragmatech.com","cover_image":"https://cdn.steemitimages.com/DQmfX8FptYvkJiGCafeg4TXJrp9r9PLsjn3uNyP9ocsDeWs/IMG_20180609_165708452_HDR-EFFECTS.jpg"}
{
  "posting_json_metadata": {
    "profile": {
      "profile_image": "https://cdn.steemitimages.com/DQmXG4wKH4Aq7y5Ypimdj7zYdFvqCpvFdeuVWmPoUgzrQgf/IMG_2306.jpg",
      "name": "Kapil Jain",
      "about": "I love to travel and meeting people with different culture.",
      "location": "Delhi, India",
      "website": "https://www.ipragmatech.com",
      "cover_image": "https://cdn.steemitimages.com/DQmfX8FptYvkJiGCafeg4TXJrp9r9PLsjn3uNyP9ocsDeWs/IMG_20180609_165708452_HDR-EFFECTS.jpg"
    }
  },
  "json_metadata": {
    "profile": {
      "profile_image": "https://cdn.steemitimages.com/DQmXG4wKH4Aq7y5Ypimdj7zYdFvqCpvFdeuVWmPoUgzrQgf/IMG_2306.jpg",
      "name": "Kapil Jain",
      "about": "I love to travel and meeting people with different culture.",
      "location": "Delhi, India",
      "website": "https://www.ipragmatech.com",
      "cover_image": "https://cdn.steemitimages.com/DQmfX8FptYvkJiGCafeg4TXJrp9r9PLsjn3uNyP9ocsDeWs/IMG_20180609_165708452_HDR-EFFECTS.jpg"
    }
  }
}

Auth Keys

Owner
Single Signature
Public Keys
STM6RxPqEahBSLbSQ81NZtyZBo3tqFmNLWrp9VkXSXSoCmXCa3vqh1/1
Active
Single Signature
Public Keys
STM6paaq2fsm2uvSkMFtZgcG6JBDwb1wQ7uHVqWecKvUuYH3FpuA71/1
Posting
Single Signature
Public Keys
STM6dDD4VUFhTRHWuNhUprcLAf2mhpDJ7Md61DtZetxRihNcrNiy71/1
App Permissions
Memo
STM8VWvWXvi26En5QneqaV5i9ni9m98fP8kNkAXPfhV7qUVhXq3YU
{
  "owner": {
    "account_auths": [],
    "key_auths": [
      [
        "STM6RxPqEahBSLbSQ81NZtyZBo3tqFmNLWrp9VkXSXSoCmXCa3vqh",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "active": {
    "account_auths": [],
    "key_auths": [
      [
        "STM6paaq2fsm2uvSkMFtZgcG6JBDwb1wQ7uHVqWecKvUuYH3FpuA7",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "posting": {
    "account_auths": [
      [
        "ipragmatech-app",
        1
      ]
    ],
    "key_auths": [
      [
        "STM6dDD4VUFhTRHWuNhUprcLAf2mhpDJ7Md61DtZetxRihNcrNiy7",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "memo": "STM8VWvWXvi26En5QneqaV5i9ni9m98fP8kNkAXPfhV7qUVhXq3YU"
}

Witness Votes

0 / 30
No active witness votes.
[]