Ecoer Logo

@exploringworld

44

Love the Nature ★ Enjoy Food ★ Care to Beauty ★ Surf the Tech

steemit.com/@exploringworld
VOTING POWER100.00%
DOWNVOTE POWER100.00%
RESOURCE CREDITS100.00%
REPUTATION PROGRESS72.54%
Net Worth
0.289USD
STEEM
0.000STEEM
SBD
0.000SBD
Effective Power
6.382SP
├── Own SP
5.356SP
└── Incoming Deleg
+1.026SP

Detailed Balance

STEEM
balance
0.000STEEM
market_balance
0.000STEEM
savings_balance
0.000STEEM
reward_steem_balance
0.000STEEM
STEEM POWER
Own SP
5.356SP
Delegated Out
0.000SP
Delegation In
1.026SP
Effective Power
6.382SP
Reward SP (pending)
0.000SP
SBD
sbd_balance
0.000SBD
sbd_conversions
0.000SBD
sbd_market_balance
0.000SBD
savings_sbd_balance
0.000SBD
reward_sbd_balance
0.000SBD
{
  "balance": "0.000 STEEM",
  "savings_balance": "0.000 STEEM",
  "reward_steem_balance": "0.000 STEEM",
  "vesting_shares": "8721.566670 VESTS",
  "delegated_vesting_shares": "0.000000 VESTS",
  "received_vesting_shares": "1670.965692 VESTS",
  "sbd_balance": "0.000 SBD",
  "savings_sbd_balance": "0.000 SBD",
  "reward_sbd_balance": "0.000 SBD",
  "conversions": []
}

Account Info

nameexploringworld
id644147
rank190,657
reputation120391195325
created2018-01-23T16:29:30
recovery_accountsteem
proxyNone
post_count58
comment_count0
lifetime_vote_count0
witnesses_voted_for0
last_post2018-05-01T12:36:39
last_root_post2018-05-01T12:36:39
last_vote_time2018-04-26T10:28:12
proxied_vsf_votes0, 0, 0, 0
can_vote1
voting_power0
delayed_votes0
balance0.000 STEEM
savings_balance0.000 STEEM
sbd_balance0.000 SBD
savings_sbd_balance0.000 SBD
vesting_shares8721.566670 VESTS
delegated_vesting_shares0.000000 VESTS
received_vesting_shares1670.965692 VESTS
reward_vesting_balance0.000000 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-05-04T13:56:33
minedNo
sbd_seconds30,429
sbd_last_interest_payment2020-11-01T09:36:06
savings_sbd_last_interest_payment1970-01-01T00:00:00
{
  "id": 644147,
  "name": "exploringworld",
  "owner": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM67Mp9MA1ha6UFFW4FaqhDmYhTjKmhx2Tre6183itJhDNMuRh9x",
        1
      ]
    ]
  },
  "active": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM5TsBxLQPfwrZeLrA32amGhkxR6tMvAiCo5vpkwCcaZSFJ9jGV7",
        1
      ]
    ]
  },
  "posting": {
    "weight_threshold": 1,
    "account_auths": [
      [
        "esteemapp",
        1
      ],
      [
        "utopian.app",
        1
      ]
    ],
    "key_auths": [
      [
        "STM5qtdLHtFCJ5UD78KnGrLsDnX9quESVqx9AP7zo5ySKUgz9GNaH",
        1
      ]
    ]
  },
  "memo_key": "STM66yD8tvh73V9fyF4iMv7mmoic3CaXXcstJ667SCNx36j6uKenj",
  "json_metadata": "{\"profile\":{\"cover_image\":\"https://i.imgur.com/dpZ1sar.jpg\",\"profile_image\":\"https://i.imgur.com/ZGTrViJ.jpg\",\"about\":\"Love the Nature ★ Enjoy Food ★ Care to Beauty ★ Surf the Tech\",\"name\":\"Exploring World\",\"location\":\"Worldwide\"}}",
  "posting_json_metadata": "{\"profile\":{\"cover_image\":\"https://i.imgur.com/dpZ1sar.jpg\",\"profile_image\":\"https://i.imgur.com/ZGTrViJ.jpg\",\"about\":\"Love the Nature ★ Enjoy Food ★ Care to Beauty ★ Surf the Tech\",\"name\":\"Exploring World\",\"location\":\"Worldwide\"}}",
  "proxy": "",
  "last_owner_update": "1970-01-01T00:00:00",
  "last_account_update": "2018-05-04T13:56:33",
  "created": "2018-01-23T16:29:30",
  "mined": false,
  "recovery_account": "steem",
  "last_account_recovery": "1970-01-01T00:00:00",
  "reset_account": "null",
  "comment_count": 0,
  "lifetime_vote_count": 0,
  "post_count": 58,
  "can_vote": true,
  "voting_manabar": {
    "current_mana": "10392532362",
    "last_update_time": 1748331093
  },
  "downvote_manabar": {
    "current_mana": 2598133090,
    "last_update_time": 1748331093
  },
  "voting_power": 0,
  "balance": "0.000 STEEM",
  "savings_balance": "0.000 STEEM",
  "sbd_balance": "0.000 SBD",
  "sbd_seconds": "30429",
  "sbd_seconds_last_update": "2020-11-01T09:40:21",
  "sbd_last_interest_payment": "2020-11-01T09:36:06",
  "savings_sbd_balance": "0.000 SBD",
  "savings_sbd_seconds": "0",
  "savings_sbd_seconds_last_update": "1970-01-01T00:00:00",
  "savings_sbd_last_interest_payment": "1970-01-01T00:00:00",
  "savings_withdraw_requests": 0,
  "reward_sbd_balance": "0.000 SBD",
  "reward_steem_balance": "0.000 STEEM",
  "reward_vesting_balance": "0.000000 VESTS",
  "reward_vesting_steem": "0.000 STEEM",
  "vesting_shares": "8721.566670 VESTS",
  "delegated_vesting_shares": "0.000000 VESTS",
  "received_vesting_shares": "1670.965692 VESTS",
  "vesting_withdraw_rate": "0.000000 VESTS",
  "next_vesting_withdrawal": "1969-12-31T23:59:59",
  "withdrawn": 0,
  "to_withdraw": 0,
  "withdraw_routes": 0,
  "curation_rewards": 0,
  "posting_rewards": 7536,
  "proxied_vsf_votes": [
    0,
    0,
    0,
    0
  ],
  "witnesses_voted_for": 0,
  "last_post": "2018-05-01T12:36:39",
  "last_root_post": "2018-05-01T12:36:39",
  "last_vote_time": "2018-04-26T10:28:12",
  "post_bandwidth": 0,
  "pending_claimed_accounts": 0,
  "vesting_balance": "0.000 STEEM",
  "reputation": "120391195325",
  "transfer_history": [],
  "market_history": [],
  "post_history": [],
  "vote_history": [],
  "other_history": [],
  "witness_votes": [],
  "tags_usage": [],
  "guest_bloggers": [],
  "rank": 190657
}

Withdraw Routes

IncomingOutgoing
Empty
Empty
{
  "incoming": [],
  "outgoing": []
}
From Date
To Date
steemdelegated 1.026 SP to @exploringworld
2025/05/27 07:31:33
delegatorsteem
delegateeexploringworld
vesting shares1670.965692 VESTS
Transaction InfoBlock #95928018/Trx e88e4fbc787ebcc292302c8406299ac4f30a087b
View Raw JSON Data
{
  "trx_id": "e88e4fbc787ebcc292302c8406299ac4f30a087b",
  "block": 95928018,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2025-05-27T07:31:33",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "exploringworld",
      "vesting_shares": "1670.965692 VESTS"
    }
  ]
}
steemdelegated 1.129 SP to @exploringworld
2022/01/11 17:05:21
delegatorsteem
delegateeexploringworld
vesting shares1838.075384 VESTS
Transaction InfoBlock #60644852/Trx c485e05be93817a05023de8d9ce37e3b0394af36
View Raw JSON Data
{
  "trx_id": "c485e05be93817a05023de8d9ce37e3b0394af36",
  "block": 60644852,
  "trx_in_block": 7,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2022-01-11T17:05:21",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "exploringworld",
      "vesting_shares": "1838.075384 VESTS"
    }
  ]
}
exploringworldsent 70.785 STEEM to @deepcrypto8- "101694645"
2020/11/01 09:49:03
fromexploringworld
todeepcrypto8
amount70.785 STEEM
memo101694645
Transaction InfoBlock #48222690/Trx 015e27c12ffc6dbe51d4a0cbbbb8088b88ea2197
View Raw JSON Data
{
  "trx_id": "015e27c12ffc6dbe51d4a0cbbbb8088b88ea2197",
  "block": 48222690,
  "trx_in_block": 7,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-11-01T09:49:03",
  "op": [
    "transfer",
    {
      "from": "exploringworld",
      "to": "deepcrypto8",
      "amount": "70.785 STEEM",
      "memo": "101694645"
    }
  ]
}
exploringworldblockchain operation: limit order create
2020/11/01 09:40:21
ownerexploringworld
orderid1604223606
amount to sell0.483 SBD
min to receive3.287 STEEM
fill or killfalse
expiration2020-11-28T09:39:42
Transaction InfoBlock #48222518/Trx 5bfcd772098bf4e252a249138ea53d3e12d2f67a
View Raw JSON Data
{
  "trx_id": "5bfcd772098bf4e252a249138ea53d3e12d2f67a",
  "block": 48222518,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-11-01T09:40:21",
  "op": [
    "limit_order_create",
    {
      "owner": "exploringworld",
      "orderid": 1604223606,
      "amount_to_sell": "0.483 SBD",
      "min_to_receive": "3.287 STEEM",
      "fill_or_kill": false,
      "expiration": "2020-11-28T09:39:42"
    }
  ]
}
exploringworldbought 3.287 STEEM for 0.483 SBD from @quicktrades
2020/11/01 09:40:21
current ownerexploringworld
current orderid1604223606
current pays0.483 SBD
open ownerquicktrades
open orderid1145556929
open pays3.287 STEEM
Transaction InfoBlock #48222518/Trx 5bfcd772098bf4e252a249138ea53d3e12d2f67a
View Raw JSON Data
{
  "trx_id": "5bfcd772098bf4e252a249138ea53d3e12d2f67a",
  "block": 48222518,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 1,
  "timestamp": "2020-11-01T09:40:21",
  "op": [
    "fill_order",
    {
      "current_owner": "exploringworld",
      "current_orderid": 1604223606,
      "current_pays": "0.483 SBD",
      "open_owner": "quicktrades",
      "open_orderid": 1145556929,
      "open_pays": "3.287 STEEM"
    }
  ]
}
exploringworldblockchain operation: limit order cancel
2020/11/01 09:39:18
ownerexploringworld
orderid1604223327
Transaction InfoBlock #48222497/Trx 2a3dfa621b32c4f9e033468a56250090ae1e0c20
View Raw JSON Data
{
  "trx_id": "2a3dfa621b32c4f9e033468a56250090ae1e0c20",
  "block": 48222497,
  "trx_in_block": 6,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-11-01T09:39:18",
  "op": [
    "limit_order_cancel",
    {
      "owner": "exploringworld",
      "orderid": 1604223327
    }
  ]
}
exploringworldbought 9.861 SBD for 67.496 STEEM from @exploringworld
2020/11/01 09:36:39
current ownerneoxag
current orderid1604223396
current pays67.496 STEEM
open ownerexploringworld
open orderid1604223327
open pays9.861 SBD
Transaction InfoBlock #48222444/Trx 51f0e0c3cc720d9b072341d037512afd643aa5f6
View Raw JSON Data
{
  "trx_id": "51f0e0c3cc720d9b072341d037512afd643aa5f6",
  "block": 48222444,
  "trx_in_block": 1,
  "op_in_trx": 0,
  "virtual_op": 2,
  "timestamp": "2020-11-01T09:36:39",
  "op": [
    "fill_order",
    {
      "current_owner": "neoxag",
      "current_orderid": 1604223396,
      "current_pays": "67.496 STEEM",
      "open_owner": "exploringworld",
      "open_orderid": 1604223327,
      "open_pays": "9.861 SBD"
    }
  ]
}
exploringworldblockchain operation: limit order create
2020/11/01 09:36:06
ownerexploringworld
orderid1604223327
amount to sell10.344 SBD
min to receive70.800 STEEM
fill or killfalse
expiration2020-11-28T09:33:52
Transaction InfoBlock #48222434/Trx 438b3341530d572c184c5697fa81d41e0e7a0bf3
View Raw JSON Data
{
  "trx_id": "438b3341530d572c184c5697fa81d41e0e7a0bf3",
  "block": 48222434,
  "trx_in_block": 2,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-11-01T09:36:06",
  "op": [
    "limit_order_create",
    {
      "owner": "exploringworld",
      "orderid": 1604223327,
      "amount_to_sell": "10.344 SBD",
      "min_to_receive": "70.800 STEEM",
      "fill_or_kill": false,
      "expiration": "2020-11-28T09:33:52"
    }
  ]
}
2020/01/23 18:38:21
parent authorexploringworld
parent permlinkadvance-ruby-development-episode-1
authorsteemitboard
permlinksteemitboard-notify-exploringworld-20200123t183821000z
title
bodyCongratulations @exploringworld! You received a personal award! <table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@exploringworld/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table> <sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@exploringworld) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=exploringworld)_</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"]}
Transaction InfoBlock #40187035/Trx d186acad55d4b4736e6bc0c202168100c4e42bf2
View Raw JSON Data
{
  "trx_id": "d186acad55d4b4736e6bc0c202168100c4e42bf2",
  "block": 40187035,
  "trx_in_block": 7,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-01-23T18:38:21",
  "op": [
    "comment",
    {
      "parent_author": "exploringworld",
      "parent_permlink": "advance-ruby-development-episode-1",
      "author": "steemitboard",
      "permlink": "steemitboard-notify-exploringworld-20200123t183821000z",
      "title": "",
      "body": "Congratulations @exploringworld! You received a personal award!\n\n<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@exploringworld/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table>\n\n<sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@exploringworld) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=exploringworld)_</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\"]}"
    }
  ]
}
dtubesent 0.001 STEEM to @exploringworld- "Time is running out, claim your DTube account now before anyone else can! Login at https://d.tube"
2019/08/22 17:18:21
fromdtube
toexploringworld
amount0.001 STEEM
memoTime is running out, claim your DTube account now before anyone else can! Login at https://d.tube
Transaction InfoBlock #35780775/Trx 244ee265fb20de3f59a0309f3d3d2cdbbb0d4aa8
View Raw JSON Data
{
  "trx_id": "244ee265fb20de3f59a0309f3d3d2cdbbb0d4aa8",
  "block": 35780775,
  "trx_in_block": 27,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2019-08-22T17:18:21",
  "op": [
    "transfer",
    {
      "from": "dtube",
      "to": "exploringworld",
      "amount": "0.001 STEEM",
      "memo": "Time is running out, claim your DTube account now before anyone else can! Login at https://d.tube"
    }
  ]
}
dsoundsent 0.001 STEEM to @exploringworld- "Hi @exploringworld! We know you love music because you are a DSound user. DSound music community needs your help! We have a community witness named @dsound that we would like you to vote for and we al..."
2019/02/03 20:47:33
fromdsound
toexploringworld
amount0.001 STEEM
memoHi @exploringworld! We know you love music because you are a DSound user. DSound music community needs your help! We have a community witness named @dsound that we would like you to vote for and we also greatly appreciate delegations of any amount, to help curation of our content since Steemit Inc removed their delegation. Delegations will be profitable soon and the first to delegate will get bigger rewards, please read @prc last post for more info... Thanks a lot for your support to DSound community! :)
Transaction InfoBlock #30033578/Trx d2b0a46613e11ae194b6f8d39d6ebe7a7db44cde
View Raw JSON Data
{
  "trx_id": "d2b0a46613e11ae194b6f8d39d6ebe7a7db44cde",
  "block": 30033578,
  "trx_in_block": 47,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2019-02-03T20:47:33",
  "op": [
    "transfer",
    {
      "from": "dsound",
      "to": "exploringworld",
      "amount": "0.001 STEEM",
      "memo": "Hi @exploringworld! We know you love music because you are a DSound user. DSound music community needs your help! We have a community witness named @dsound that we would like you to vote for and we also greatly appreciate delegations of any amount, to help curation of our content since Steemit Inc removed their delegation. Delegations will be profitable soon and the first to delegate will get bigger rewards, please read @prc last post for more info... Thanks a lot for your support to DSound community! :)"
    }
  ]
}
2019/01/23 19:32:45
parent authorexploringworld
parent permlinkadvance-ruby-development-episode-1
authorsteemitboard
permlinksteemitboard-notify-exploringworld-20190123t193245000z
title
bodyCongratulations @exploringworld! You received a personal award! <table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@exploringworld/birthday1.png</td><td>Happy Birthday! - You are on the Steem blockchain for 1 year!</td></tr></table> <sub>_[Click here to view your Board](https://steemitboard.com/@exploringworld)_</sub> > Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
Transaction InfoBlock #29715610/Trx 09713d7c411ff7387a41192be2a7cf1f8b86da12
View Raw JSON Data
{
  "trx_id": "09713d7c411ff7387a41192be2a7cf1f8b86da12",
  "block": 29715610,
  "trx_in_block": 11,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2019-01-23T19:32:45",
  "op": [
    "comment",
    {
      "parent_author": "exploringworld",
      "parent_permlink": "advance-ruby-development-episode-1",
      "author": "steemitboard",
      "permlink": "steemitboard-notify-exploringworld-20190123t193245000z",
      "title": "",
      "body": "Congratulations @exploringworld! You received a personal award!\n\n<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@exploringworld/birthday1.png</td><td>Happy Birthday! - You are on the Steem blockchain for 1 year!</td></tr></table>\n\n<sub>_[Click here to view your Board](https://steemitboard.com/@exploringworld)_</sub>\n\n\n> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}"
    }
  ]
}
steemdelegated 1.242 SP to @exploringworld
2018/09/14 15:37:30
delegatorsteem
delegateeexploringworld
vesting shares2021.886550 VESTS
Transaction InfoBlock #25956470/Trx 64f91c1245f84222cba766cd55ceeadd03057ffe
View Raw JSON Data
{
  "trx_id": "64f91c1245f84222cba766cd55ceeadd03057ffe",
  "block": 25956470,
  "trx_in_block": 19,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-09-14T15:37:30",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "exploringworld",
      "vesting_shares": "2021.886550 VESTS"
    }
  ]
}
2018/07/06 11:57:18
voterirfan786
authorexploringworld
permlinkre-amrantaj-pakistan-super-league-2018-schedule-cricket-match-when-and-where-and-players-list-20180127t164323703z
weight10000 (100.00%)
Transaction InfoBlock #23937464/Trx 668e80cc446f9d8160b3658a2ab19c416c5b08b8
View Raw JSON Data
{
  "trx_id": "668e80cc446f9d8160b3658a2ab19c416c5b08b8",
  "block": 23937464,
  "trx_in_block": 50,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-07-06T11:57:18",
  "op": [
    "vote",
    {
      "voter": "irfan786",
      "author": "exploringworld",
      "permlink": "re-amrantaj-pakistan-super-league-2018-schedule-cricket-match-when-and-where-and-players-list-20180127t164323703z",
      "weight": 10000
    }
  ]
}
steemdelegated 13.359 SP to @exploringworld
2018/06/15 13:00:21
delegatorsteem
delegateeexploringworld
vesting shares21753.741777 VESTS
Transaction InfoBlock #23343968/Trx 6aa60e62b33da98e033e29703188c596bd6d5713
View Raw JSON Data
{
  "trx_id": "6aa60e62b33da98e033e29703188c596bd6d5713",
  "block": 23343968,
  "trx_in_block": 37,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-06-15T13:00:21",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "exploringworld",
      "vesting_shares": "21753.741777 VESTS"
    }
  ]
}
exploringworldclaimed reward balance: 1.353 SBD, 0.433 SP
2018/06/15 12:01:09
accountexploringworld
reward steem0.000 STEEM
reward sbd1.353 SBD
reward vests704.565225 VESTS
Transaction InfoBlock #23342784/Trx dc8ce1143af5ac3890871ab7e31b02a3ec42968b
View Raw JSON Data
{
  "trx_id": "dc8ce1143af5ac3890871ab7e31b02a3ec42968b",
  "block": 23342784,
  "trx_in_block": 12,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-06-15T12:01:09",
  "op": [
    "claim_reward_balance",
    {
      "account": "exploringworld",
      "reward_steem": "0.000 STEEM",
      "reward_sbd": "1.353 SBD",
      "reward_vests": "704.565225 VESTS"
    }
  ]
}
2018/05/27 16:08:57
votersalocin.ten
authorexploringworld
permlinkdevelop-mobile-apps-using-ionic-framework-part-1
weight10000 (100.00%)
Transaction InfoBlock #22801253/Trx 8b9bc51949cc1b696a5bcd01ae5627c1bcd0fd3e
View Raw JSON Data
{
  "trx_id": "8b9bc51949cc1b696a5bcd01ae5627c1bcd0fd3e",
  "block": 22801253,
  "trx_in_block": 28,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-27T16:08:57",
  "op": [
    "vote",
    {
      "voter": "salocin.ten",
      "author": "exploringworld",
      "permlink": "develop-mobile-apps-using-ionic-framework-part-1",
      "weight": 10000
    }
  ]
}
exploringworldreceived 0.018 SBD, 0.006 SP author reward for @exploringworld / advance-ruby-development-episode-1
2018/05/08 12:36:39
authorexploringworld
permlinkadvance-ruby-development-episode-1
sbd payout0.018 SBD
steem payout0.000 STEEM
vesting payout10.178670 VESTS
Transaction InfoBlock #22250260/Virtual Operation #17
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 22250260,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 17,
  "timestamp": "2018-05-08T12:36:39",
  "op": [
    "author_reward",
    {
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "sbd_payout": "0.018 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "10.178670 VESTS"
    }
  ]
}
utopian.payreceived 0.001 SP benefactor reward from @exploringworld
2018/05/08 12:36:39
benefactorutopian.pay
authorexploringworld
permlinkadvance-ruby-development-episode-1
sbd payout0.000 SBD
steem payout0.000 STEEM
vesting payout2.035734 VESTS
Transaction InfoBlock #22250260/Virtual Operation #16
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 22250260,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 16,
  "timestamp": "2018-05-08T12:36:39",
  "op": [
    "comment_benefactor_reward",
    {
      "benefactor": "utopian.pay",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "2.035734 VESTS"
    }
  ]
}
2018/05/07 16:01:51
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"corina","what":["blog"]}]
Transaction InfoBlock #22225568/Trx 3651e28ca801d2fabfed1fc189ec96cda03444df
View Raw JSON Data
{
  "trx_id": "3651e28ca801d2fabfed1fc189ec96cda03444df",
  "block": 22225568,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T16:01:51",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"corina\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 16:01:33
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"mohsin01","what":["blog"]}]
Transaction InfoBlock #22225562/Trx 1c69bb50d4ab5d6ede94d8bf2fe04b2424c870d3
View Raw JSON Data
{
  "trx_id": "1c69bb50d4ab5d6ede94d8bf2fe04b2424c870d3",
  "block": 22225562,
  "trx_in_block": 12,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T16:01:33",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"mohsin01\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 16:01:24
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"hanen","what":["blog"]}]
Transaction InfoBlock #22225559/Trx 7d91f67f5ff378b24fbbca2f8a43c8cf85c4f094
View Raw JSON Data
{
  "trx_id": "7d91f67f5ff378b24fbbca2f8a43c8cf85c4f094",
  "block": 22225559,
  "trx_in_block": 23,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T16:01:24",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"hanen\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 16:01:09
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"nathen007","what":["blog"]}]
Transaction InfoBlock #22225554/Trx 5851c5742a49cfd4fd70bf6d29f109d27f2d2dcb
View Raw JSON Data
{
  "trx_id": "5851c5742a49cfd4fd70bf6d29f109d27f2d2dcb",
  "block": 22225554,
  "trx_in_block": 4,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T16:01:09",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"nathen007\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 16:00:57
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"hyperfundit.com","what":["blog"]}]
Transaction InfoBlock #22225550/Trx bd533d450dd84e3f8d36cce2cf76ae604c5a14bd
View Raw JSON Data
{
  "trx_id": "bd533d450dd84e3f8d36cce2cf76ae604c5a14bd",
  "block": 22225550,
  "trx_in_block": 36,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T16:00:57",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"hyperfundit.com\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 16:00:06
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"jie28","what":["blog"]}]
Transaction InfoBlock #22225533/Trx f40b74d199cc13940ab86c6525c832a73cf523e9
View Raw JSON Data
{
  "trx_id": "f40b74d199cc13940ab86c6525c832a73cf523e9",
  "block": 22225533,
  "trx_in_block": 68,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T16:00:06",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"jie28\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 15:59:57
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"artedellavita","what":["blog"]}]
Transaction InfoBlock #22225530/Trx 88c723a3fbd27848d106507f361602a5c646a3f6
View Raw JSON Data
{
  "trx_id": "88c723a3fbd27848d106507f361602a5c646a3f6",
  "block": 22225530,
  "trx_in_block": 16,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T15:59:57",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"artedellavita\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 15:59:33
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"simply-me","what":["blog"]}]
Transaction InfoBlock #22225522/Trx 9a56637bedcb9724d0f3fd65ea2a2497d8e20ba4
View Raw JSON Data
{
  "trx_id": "9a56637bedcb9724d0f3fd65ea2a2497d8e20ba4",
  "block": 22225522,
  "trx_in_block": 15,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T15:59:33",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"simply-me\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 15:59:18
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"duartenunes","what":["blog"]}]
Transaction InfoBlock #22225517/Trx 351e3d8cb9966326a9e7c680e6d2f777506f7bf1
View Raw JSON Data
{
  "trx_id": "351e3d8cb9966326a9e7c680e6d2f777506f7bf1",
  "block": 22225517,
  "trx_in_block": 30,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T15:59:18",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"duartenunes\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 15:59:09
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"jfitmisc","what":["blog"]}]
Transaction InfoBlock #22225514/Trx 8f4d9ba58596fc88aadd344664ad818ac4ad8efb
View Raw JSON Data
{
  "trx_id": "8f4d9ba58596fc88aadd344664ad818ac4ad8efb",
  "block": 22225514,
  "trx_in_block": 29,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T15:59:09",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"jfitmisc\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 15:59:03
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"hiroyamagishi","what":["blog"]}]
Transaction InfoBlock #22225512/Trx 23f18f25f14ae8195e63ab84782d229fbcd7aba3
View Raw JSON Data
{
  "trx_id": "23f18f25f14ae8195e63ab84782d229fbcd7aba3",
  "block": 22225512,
  "trx_in_block": 6,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T15:59:03",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"hiroyamagishi\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 15:58:42
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"chronocrypto","what":["blog"]}]
Transaction InfoBlock #22225505/Trx 6333390056fc94befd2efed894784668eb657375
View Raw JSON Data
{
  "trx_id": "6333390056fc94befd2efed894784668eb657375",
  "block": 22225505,
  "trx_in_block": 13,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T15:58:42",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"chronocrypto\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/07 15:57:18
required auths[]
required posting auths["exploringworld"]
idfollow
json["follow",{"follower":"exploringworld","following":"good-karma","what":["blog"]}]
Transaction InfoBlock #22225477/Trx 8a183ed6ce63a1c4de306e777255fea88256c55d
View Raw JSON Data
{
  "trx_id": "8a183ed6ce63a1c4de306e777255fea88256c55d",
  "block": 22225477,
  "trx_in_block": 54,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-07T15:57:18",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "exploringworld"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"exploringworld\",\"following\":\"good-karma\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/05/06 00:21:06
authorexploringworld
permlinkbuild-complete-full-stack-web-app-using-go-programming-language
sbd payout0.027 SBD
steem payout0.000 STEEM
vesting payout16.287991 VESTS
Transaction InfoBlock #22177971/Virtual Operation #16
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 22177971,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 16,
  "timestamp": "2018-05-06T00:21:06",
  "op": [
    "author_reward",
    {
      "author": "exploringworld",
      "permlink": "build-complete-full-stack-web-app-using-go-programming-language",
      "sbd_payout": "0.027 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "16.287991 VESTS"
    }
  ]
}
utopian.payreceived 0.003 SP benefactor reward from @exploringworld
2018/05/06 00:21:06
benefactorutopian.pay
authorexploringworld
permlinkbuild-complete-full-stack-web-app-using-go-programming-language
sbd payout0.000 SBD
steem payout0.000 STEEM
vesting payout4.071997 VESTS
Transaction InfoBlock #22177971/Virtual Operation #15
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 22177971,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 15,
  "timestamp": "2018-05-06T00:21:06",
  "op": [
    "comment_benefactor_reward",
    {
      "benefactor": "utopian.pay",
      "author": "exploringworld",
      "permlink": "build-complete-full-stack-web-app-using-go-programming-language",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "4.071997 VESTS"
    }
  ]
}
2018/05/04 21:44:30
authorexploringworld
permlinkdevelop-mobile-apps-using-ionic-framework-part-2
sbd payout0.019 SBD
steem payout0.000 STEEM
vesting payout10.180578 VESTS
Transaction InfoBlock #22146058/Virtual Operation #5
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 22146058,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 5,
  "timestamp": "2018-05-04T21:44:30",
  "op": [
    "author_reward",
    {
      "author": "exploringworld",
      "permlink": "develop-mobile-apps-using-ionic-framework-part-2",
      "sbd_payout": "0.019 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "10.180578 VESTS"
    }
  ]
}
utopian.payreceived 0.001 SP benefactor reward from @exploringworld
2018/05/04 21:44:30
benefactorutopian.pay
authorexploringworld
permlinkdevelop-mobile-apps-using-ionic-framework-part-2
sbd payout0.000 SBD
steem payout0.000 STEEM
vesting payout2.036115 VESTS
Transaction InfoBlock #22146058/Virtual Operation #4
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 22146058,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 4,
  "timestamp": "2018-05-04T21:44:30",
  "op": [
    "comment_benefactor_reward",
    {
      "benefactor": "utopian.pay",
      "author": "exploringworld",
      "permlink": "develop-mobile-apps-using-ionic-framework-part-2",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "2.036115 VESTS"
    }
  ]
}
exploringworldupdated their account properties
2018/05/04 13:56:33
accountexploringworld
posting{"weight_threshold":1,"account_auths":[["esteemapp",1],["utopian.app",1]],"key_auths":[["STM5qtdLHtFCJ5UD78KnGrLsDnX9quESVqx9AP7zo5ySKUgz9GNaH",1]]}
memo keySTM66yD8tvh73V9fyF4iMv7mmoic3CaXXcstJ667SCNx36j6uKenj
json metadata{"profile":{"cover_image":"https://i.imgur.com/dpZ1sar.jpg","profile_image":"https://i.imgur.com/ZGTrViJ.jpg","about":"Love the Nature ★ Enjoy Food ★ Care to Beauty ★ Surf the Tech","name":"Exploring World","location":"Worldwide"}}
Transaction InfoBlock #22136701/Trx 76cf83a0c00309f089fb613c4a63b2120d682c22
View Raw JSON Data
{
  "trx_id": "76cf83a0c00309f089fb613c4a63b2120d682c22",
  "block": 22136701,
  "trx_in_block": 16,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-04T13:56:33",
  "op": [
    "account_update",
    {
      "account": "exploringworld",
      "posting": {
        "weight_threshold": 1,
        "account_auths": [
          [
            "esteemapp",
            1
          ],
          [
            "utopian.app",
            1
          ]
        ],
        "key_auths": [
          [
            "STM5qtdLHtFCJ5UD78KnGrLsDnX9quESVqx9AP7zo5ySKUgz9GNaH",
            1
          ]
        ]
      },
      "memo_key": "STM66yD8tvh73V9fyF4iMv7mmoic3CaXXcstJ667SCNx36j6uKenj",
      "json_metadata": "{\"profile\":{\"cover_image\":\"https://i.imgur.com/dpZ1sar.jpg\",\"profile_image\":\"https://i.imgur.com/ZGTrViJ.jpg\",\"about\":\"Love the Nature ★ Enjoy Food ★ Care to Beauty ★ Surf the Tech\",\"name\":\"Exploring World\",\"location\":\"Worldwide\"}}"
    }
  ]
}
2018/05/03 23:00:09
authorexploringworld
permlinkqnj1e-develop-mobile-apps-using-ionic-framework-part-1
sbd payout0.015 SBD
steem payout0.000 STEEM
vesting payout8.144862 VESTS
Transaction InfoBlock #22118776/Virtual Operation #5
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 22118776,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 5,
  "timestamp": "2018-05-03T23:00:09",
  "op": [
    "author_reward",
    {
      "author": "exploringworld",
      "permlink": "qnj1e-develop-mobile-apps-using-ionic-framework-part-1",
      "sbd_payout": "0.015 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "8.144862 VESTS"
    }
  ]
}
utopian.payreceived 0.001 SP benefactor reward from @exploringworld
2018/05/03 23:00:09
benefactorutopian.pay
authorexploringworld
permlinkqnj1e-develop-mobile-apps-using-ionic-framework-part-1
sbd payout0.000 SBD
steem payout0.000 STEEM
vesting payout2.036215 VESTS
Transaction InfoBlock #22118776/Virtual Operation #4
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 22118776,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 4,
  "timestamp": "2018-05-03T23:00:09",
  "op": [
    "comment_benefactor_reward",
    {
      "benefactor": "utopian.pay",
      "author": "exploringworld",
      "permlink": "qnj1e-develop-mobile-apps-using-ionic-framework-part-1",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "2.036215 VESTS"
    }
  ]
}
2018/05/03 05:11:48
parent authorexploringworld
parent permlinkdevelop-mobile-apps-using-ionic-framework-part-1
authorsteembottrackerr
permlink20180503t051146094z
title
body<center>https://steemitimages.com/200x200/https://s-media-cache-ak0.pinimg.com/originals/81/28/3c/81283c6aed7bdb5b9f8ad73b8ce62c2f.jpg</center> --- <center>Hello @exploringworld , Congratulations ✅ . Your content began to appear in the hot section. I am the information account of "SteemBotTracker" site. </center> --- <center> Your Informations Total SBD: 8.988 Total STEEM: 0 </center> --- <center> I recommend to increase this; You can make "Resteem" and advertise to the followers of the whale accounts. "Resteem Bot" for you; ✅ The most profitable Resteem Whale @hottopic has 18.500 Followers + 5200 Sp + Upvote with min +45 accounts. </center> --- <center> You can purchase "upvote" by bid bots. "Upvote Bot" ✅ The most profitable whale in the last round. @rocky1 </center> --- <center> I'm taking this message once. You need to use the #steembottrackerr tag for more information. Those who "upvote" this interpretation will be awarded a "UpVote" prize of 100 Sbd per week per person. I am a bot, I can not answer the comment. I hope I could help. Good luck. Sorry if I disturbed you. </center>
json metadata{"tags":["advice"],"app":"steemjs/test"}
Transaction InfoBlock #22097419/Trx e4219095c8faac5d3dd1c77f61e5d2f1182892c7
View Raw JSON Data
{
  "trx_id": "e4219095c8faac5d3dd1c77f61e5d2f1182892c7",
  "block": 22097419,
  "trx_in_block": 24,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-03T05:11:48",
  "op": [
    "comment",
    {
      "parent_author": "exploringworld",
      "parent_permlink": "develop-mobile-apps-using-ionic-framework-part-1",
      "author": "steembottrackerr",
      "permlink": "20180503t051146094z",
      "title": "",
      "body": "<center>https://steemitimages.com/200x200/https://s-media-cache-ak0.pinimg.com/originals/81/28/3c/81283c6aed7bdb5b9f8ad73b8ce62c2f.jpg</center>\r\n---\r\n<center>Hello @exploringworld , Congratulations ✅ . Your content began to appear in the hot section.\r\nI am the information account of \"SteemBotTracker\" site.\r\n</center>\r\n---\r\n<center>\r\nYour Informations\r\nTotal SBD: 8.988\r\nTotal STEEM: 0\r\n</center>\r\n---\r\n<center>\r\nI recommend to increase this;\r\nYou can make \"Resteem\" and advertise to the followers of the whale accounts.\r\n\"Resteem Bot\" for you;\r\n✅ The most profitable Resteem Whale @hottopic  has 18.500 Followers + 5200 Sp + Upvote with min +45 accounts. \r\n</center>\r\n---\r\n<center>\r\nYou can purchase \"upvote\" by bid bots.\r\n\"Upvote Bot\"\r\n✅ The most profitable whale in the last round. @rocky1\r\n</center>\r\n---\r\n<center>\r\nI'm taking this message once. You need to use the #steembottrackerr tag for more information.\r\nThose who \"upvote\" this interpretation will be awarded a \"UpVote\" prize of 100 Sbd per week per person.\r\nI am a bot, I can not answer the comment. I hope I could help. Good luck. Sorry if I disturbed you.\r\n</center>",
      "json_metadata": "{\"tags\":[\"advice\"],\"app\":\"steemjs/test\"}"
    }
  ]
}
2018/05/02 19:26:24
authorexploringworld
permlinkdevelop-mobile-apps-using-ionic-framework-part-1
sbd payout1.274 SBD
steem payout0.000 STEEM
vesting payout659.773124 VESTS
Transaction InfoBlock #22085710/Virtual Operation #41
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 22085710,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 41,
  "timestamp": "2018-05-02T19:26:24",
  "op": [
    "author_reward",
    {
      "author": "exploringworld",
      "permlink": "develop-mobile-apps-using-ionic-framework-part-1",
      "sbd_payout": "1.274 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "659.773124 VESTS"
    }
  ]
}
utopian.payreceived 0.143 SP benefactor reward from @exploringworld
2018/05/02 19:26:24
benefactorutopian.pay
authorexploringworld
permlinkdevelop-mobile-apps-using-ionic-framework-part-1
sbd payout0.000 SBD
steem payout0.000 STEEM
vesting payout232.142395 VESTS
Transaction InfoBlock #22085710/Virtual Operation #40
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 22085710,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 40,
  "timestamp": "2018-05-02T19:26:24",
  "op": [
    "comment_benefactor_reward",
    {
      "benefactor": "utopian.pay",
      "author": "exploringworld",
      "permlink": "develop-mobile-apps-using-ionic-framework-part-1",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "232.142395 VESTS"
    }
  ]
}
2018/05/01 21:53:51
parent authorexploringworld
parent permlinkadvance-ruby-development-episode-1
authorportugalcoin
permlinkre-exploringworld-advance-ruby-development-episode-1-20180501t215351833z
title
bodyYour contribution cannot be approved because it does not follow the Utopian Rules. - Submissions focused on the use of functions that are already well documented in the project documentation will be rejected. <a href="https://www.tutorialspoint.com/ruby/index.htm">Link</a> ---------------------------------------------------------------------- Need help? Write a ticket on https://support.utopian.io. Chat with us on [Discord](https://discord.gg/uTyJkNm). **[[utopian-moderator]](https://utopian.io/moderators)**
json metadata{"tags":["utopian-io"],"community":"utopian","app":"utopian/1.0.0"}
Transaction InfoBlock #22059864/Trx 4a7f38051fc8a3c90111e722b340abc32bd238f0
View Raw JSON Data
{
  "trx_id": "4a7f38051fc8a3c90111e722b340abc32bd238f0",
  "block": 22059864,
  "trx_in_block": 30,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T21:53:51",
  "op": [
    "comment",
    {
      "parent_author": "exploringworld",
      "parent_permlink": "advance-ruby-development-episode-1",
      "author": "portugalcoin",
      "permlink": "re-exploringworld-advance-ruby-development-episode-1-20180501t215351833z",
      "title": "",
      "body": "Your contribution cannot be approved because it does not follow the Utopian Rules.\n- Submissions focused on the use of functions that are already well documented in the project documentation will be rejected. <a href=\"https://www.tutorialspoint.com/ruby/index.htm\">Link</a>\n\n----------------------------------------------------------------------\nNeed help? Write a ticket on https://support.utopian.io.\nChat with us on [Discord](https://discord.gg/uTyJkNm).\n\n**[[utopian-moderator]](https://utopian.io/moderators)**",
      "json_metadata": "{\"tags\":[\"utopian-io\"],\"community\":\"utopian\",\"app\":\"utopian/1.0.0\"}"
    }
  ]
}
2018/05/01 21:52:45
parent author
parent permlinkutopian-io
authorexploringworld
permlinkadvance-ruby-development-episode-1
titleAdvance Ruby Development Episode-1
body#### Welcome to the First Tutorial of Advance Ruby Development <center> <img src= https://imgur.com/MILXLd2.jpg/> </center> #### What Will I Learn? - You will learn how to develop Applications using Ruby - You will learn about IRB shell in Ruby programming - You will learn about various class methods and their usage - Your will learn about reading and writing through class methods #### Requirements ##### System Requirements: - [Ruby Installer]( https://www.ruby-lang.org/en/downloads/) for building apps - [SciTE]( https://www.scintilla.org/ScintillaDownload.html) for code editing - Command Prompt or Terminal ##### OS Support: - Windows 7/8/10 - macOS - Linux #### Difficulty - Intermediate #### Required Understanding - You just need a little bit of knowledge basic Ruby Syntax - A fair understanding of Programming - A thirst for learning and developing something new #### Description - In this Advance Ruby Development course, I will teach you the advanced concepts of the Ruby programming language. Ruby was designed to be more powerful that Perl, and more object-oriented than Python, and has gained in popularity due to its power and ease of use. By the end of this course you will surely develop some powerful and concrete applications. Also in the end of this course we will be developing a Restaurant finder app. #### What is Ruby? Ruby is an object-oriented, general purpose programming language designed by Yukihiro Matsumoto in the 1990s. Intended for improved productivity and entertaining, it creates a great starter language for first time programmers because of its simplicity, readability and concentrate on fun. Commonly used with Rails applications, that is a very popular language that is always in popularity. Organizations such as Twitter and Kickstarter utilize Ruby. With Ruby, almost everything is an object. Every bit of information as well as codes can be provided their very own attributes and actions. Object-oriented programming calls attributes by the title instance variables and also actions tend to be known as methods. Ruby’s genuine object-oriented approach is quite commonly demonstrated with a bit of code that is applicable an action to a number. ``` 7.times { print "I *like* Open Source Projects" } ``` As an example, addition is conducted with the `plus (+)` operator. However, if you would instead use the readable word `plus`, you can add this type of method to Ruby’s builtin Numeric class. ``` class Numeric def plus(x) self.+(x) end end y = 4.plus 3 ``` `which results in the value of y=7 ` #### What is Interactive Ruby Shell (IRB) ? Interactive Ruby Shell (IRB ) is actually a REPL with regard to coding in the Ruby Language. Typically the abbreviation irb originates from the point that the filename extension for Ruby is **.rb**, even though interactive Ruby files don’t have an extension involving **.irb**. The program will be launched from the command line and enables the execution of Ruby commands with immediate response, testing in real-time. This features command record, line modifying capabilities, and job control, and it is capable of communicate directly being a shell script on the internet and also connect to a live server. `irb [ options ] [ programfile ] [ argument... ] ` ##### Example: ``` irb(main):001:0> num = 4 => 4 irb(main):002:0> def fact(num) irb(main):003:1> if num <= 1 irb(main):004:2> 1 irb(main):005:2> else irb(main):006:2* num * fact(num - 1) irb(main):007:2> end irb(main):008:1> end => :fact irb(main):009:0> fact(num) => 24 ``` Methods In Ruby Programming Ruby uses methods to use a block of codes. In other programming languages some other techniques are used like functions and procedures. Now we will have al look at methods in ruby and then we proceed to the next level. **Let have a look at this example** ``` def course puts "This course is about Ruby Programming " end def sub puts 7-3 end # Underscore can be used between words, like variable names in this case def longest_word words = ['pineapple', 'orange', 'mango', 'watermelon'] longest_word = words.inject do |memo,word| memo.length > word.length ? memo : word end puts longest_word end # Useful for tests and Booleans values def greater_seven? value = 7 puts value > 7 ? 'More than 7' : 'Less than 7' end ``` In the above example I define four methods which are `course,sub,longest_word and greater_seven` Behaviour: `course`: It simply displays a message on the screen which is in this case is “This course is about Ruby Programming ” `sub`:This method simply perform the subtraction of two number which is passed as arguments which are 7 and 3 `longest_word`: This method does a little interesting job here,it returns me the longest word out of an array of four words by using the `inject` function which accumulates and returns the longest length word by increment the memo each time. `greater_seven?`: This methods basically testing which number is greater between the two and returns the Boolean value. It uses `?`at its end #### Reading and Writing Operations: Ruby has methods for Reading and Writing known as Reader and Writer. Other languages have getters and setter for this reading/writing in programs. These methods will allow us to read data from a program or write data to it. Later these operations will help us in making our restaurant finder app. #### Example: ``` class Person def set_noise(noise) @noise = noise end def make_noise @noise end end person_one = Person.new person_one.set_noise("Laugh!") puts person_one.make_noise person_two = Person.new person_two.set_noise("Groan!") puts person_two.make_noise ``` Now this is a very common feature of object-oriented programming languages, sometimes in other languages, they're called getter and setter methods. Either one is fine. You can use either name, typically in Ruby, we're going to call them reader and writer methods. So, here is the code which is a perfect example to explain, what we're looking for is a pairing of something that will set a value for us and something that will get a value for us, and that's exactly what we already have with our two methods The first one is a setter method or a writer method. So we're setting the value of noise equal to a value, and this is the classic format for what a setter method would look like. `set_noise` equal to a value. It sets it for us. Then we have a `get_noise`. It's a getter method. The idea is that we are getting that value back. One of these methods sets it, one of them gets it. Now the important thing about these two methods is that they give us access control over these instance variables. So for **example**: ``` class Person def set_noise(noise) @noise = noise end person_one = Person.new person_one.set_noise("Laugh!") puts person_one.make_noise person_two = Person.new person_two.set_noise("Groan!") puts person_two.make_noise ``` if we were to take away `get_noise`, now we have no way to get that value back. Of course, we could write another method that would do it for us, but our getter method is gone ``` class Person def make_noise @noise end end person_one = Person.new person_one.set_noise("Laugh!") puts person_one.make_noise person_two = Person.new person_two.set_noise("Groan!") puts person_two.make_noise ``` Same thing here, if we were to take away `set_noise`, now we have no way to set it by calling a method. we need a setter method if we want to be able to do it directly. Like `set_noise` and `get_noise` and using underscore writing approach is very common in a lot of programming languages. In Ruby though, we can make use of that syntactic sugar that we looked at earlier, and so we can take get _out and simply ask for noise. So it asks Person to do the method noise, which returns the instance variable, noise. It's a very commonsense approach. ``` class Person def noise=(noise) @noise = noise end def noise @noise end end person_one = Person.new person_one.noise = "Laugh!" puts person_one.noise person_two = Person.new person_two.noise = "Groan!" puts person_two.noise ``` So now` person_one.noise` and `person_two.noise` just returns that to us, where the syntactic sugar comes in is that we can do the same thing with set, we can take away set and just say `noise=(noise).` #### Summary In this tutorial of Advance Ruby Development we learn about the methods, also now we have a better understanding of reading and writing using methods in Ruby. In the next tutorial we will learn about modules and development of our Restaurant Finder App.
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":538746,"name":"ruby","full_name":"ruby/ruby","html_url":"https://github.com/ruby/ruby","fork":false,"owner":{"login":"ruby"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","ruby","app","development","utopian-io"],"users":["noise"],"moderator":{"account":"portugalcoin","time":"2018-05-01T21:52:46.827Z","pending":false,"reviewed":false,"flagged":true},"questions":{"voters":["engr-muneeb"],"answers":[{"question_id":"tuts-1","answer_id":"tuts-1-a-2","user":"engr-muneeb","influence":0},{"question_id":"tuts-2","answer_id":"tuts-2-a-1","user":"engr-muneeb","influence":0},{"question_id":"tuts-3","answer_id":"tuts-3-a-2","user":"engr-muneeb","influence":0},{"question_id":"tuts-4","answer_id":"tuts-4-a-2","user":"engr-muneeb","influence":0},{"question_id":"tuts-5","answer_id":"tuts-5-a-1","user":"engr-muneeb","influence":0},{"question_id":"tuts-6","answer_id":"tuts-6-a-1","user":"engr-muneeb","influence":0},{"question_id":"c-1","answer_id":"c-1-a-1","user":"engr-muneeb","influence":0},{"question_id":"c-2","answer_id":"c-2-a-1","user":"engr-muneeb","influence":0}],"total_influence":0,"most_rated":[{"question_id":"tuts-1","answer_id":"tuts-1-a-1","influence":0,"voters":[]},{"question_id":"tuts-2","answer_id":"tuts-2-a-1","influence":0,"voters":["engr-muneeb"]},{"question_id":"tuts-3","answer_id":"tuts-3-a-1","influence":0,"voters":[]},{"question_id":"tuts-4","answer_id":"tuts-4-a-1","influence":0,"voters":[]},{"question_id":"tuts-5","answer_id":"tuts-5-a-1","influence":0,"voters":["engr-muneeb"]},{"question_id":"tuts-6","answer_id":"tuts-6-a-1","influence":0,"voters":["engr-muneeb"]},{"question_id":"c-1","answer_id":"c-1-a-1","influence":0,"voters":["engr-muneeb"]},{"question_id":"c-2","answer_id":"c-2-a-1","influence":0,"voters":["engr-muneeb"]}]},"score":100,"total_influence":0,"staff_pick":null,"staff_pick_by":null,"config":{"questions":[{"question":"How many substantial concepts does this tutorial address?","question_id":"tuts-1","answers":[{"answer":"4-5 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-1","value":10},{"answer":"2-3 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-2","value":7},{"answer":"1 substantial concept covered in the tutorial.","answer_id":"tuts-1-a-3","value":3},{"answer":"More than 5 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-4","value":0}]},{"question":"Does the title and the outline of the tutorial properly reflect the content?","question_id":"tuts-2","answers":[{"answer":"Yes, it is very clear.","answer_id":"tuts-2-a-1","value":15},{"answer":"To some extent.","answer_id":"tuts-2-a-2","value":11.5},{"answer":"The title is somewhat misleading and/or the outline is not detailed or informative enough.","answer_id":"tuts-2-a-3","value":4.5},{"answer":"Title and outline are of little or no relevance to the content of the tutorial.","answer_id":"tuts-2-a-4","value":0}]},{"question":"Did the contributor provide supplementary resources, such as code and sample files in the contribution post or a linked GitHub repository?","question_id":"tuts-3","answers":[{"answer":"Yes, exceptional supplementary resources are provided including a relevant github repo/gist.","answer_id":"tuts-3-a-1","value":15},{"answer":"Supplementary resources provided are of high relevance.","answer_id":"tuts-3-a-2","value":12},{"answer":"Contributor provides minimal supplementary resources.","answer_id":"tuts-3-a-3","value":6},{"answer":"No supplementary resources were provided.","answer_id":"tuts-3-a-4","value":0}]},{"question":"Is the tutorial part of a series?","question_id":"tuts-4","answers":[{"answer":"Yes.","answer_id":"tuts-4-a-1","value":10},{"answer":"Yes, but it is the first entry in the series.","answer_id":"tuts-4-a-2","value":7},{"answer":"No, but it works just fine as a stand-alone tutorial.","answer_id":"tuts-4-a-3","value":5},{"answer":"No.","answer_id":"tuts-4-a-4","value":0}]},{"question":"Does the tutorial contain sufficient explanatory visuals?","question_id":"tuts-5","answers":[{"answer":"Yes, the visual components of the post were adequate in quality and quantity.","answer_id":"tuts-5-a-1","value":10},{"answer":"The volume of visual components included was unnecessarily large.","answer_id":"tuts-5-a-2","value":7},{"answer":"The post lacked sufficient visualization to easily learn from the content.","answer_id":"tuts-5-a-3","value":3},{"answer":"No visualization was presented in this contribution.","answer_id":"tuts-5-a-4","value":0}]},{"question":"How unique and/or innovative are the concepts covered in the tutorial?","question_id":"tuts-6","answers":[{"answer":"This was the first time I read about the concepts covered.","answer_id":"tuts-6-a-1","value":10},{"answer":"The concepts covered were innovative and offer some usefulness.","answer_id":"tuts-6-a-2","value":7},{"answer":"I have read several similar ideas and thoughts elsewhere, but this one was of higher quality.","answer_id":"tuts-6-a-3","value":5},{"answer":"Such tutorials can be found online with great ease and the contribution add no value to the open source community.","answer_id":"tuts-6-a-4","value":0}]},{"question":"How would you describe the formatting, language and overall presentation of the post?","question_id":"c-1","answers":[{"answer":"The post is of very high quality.","answer_id":"c-1-a-1","value":10},{"answer":"The post is of decent quality, but not spectacular in any way.","answer_id":"c-1-a-2","value":7},{"answer":"The post is poorly written and/or formatted, but readable.","answer_id":"c-1-a-3","value":3},{"answer":"The post is really hard to read and the content is barely understandable.","answer_id":"c-1-a-4","value":0}]},{"question":"How would you rate the overall value of this contribution on the open source community and ecosystem?","question_id":"c-2","answers":[{"answer":"This contribution brings great and impactful value, and can be used for applications outside the specific project.","answer_id":"c-2-a-1","value":20},{"answer":"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.","answer_id":"c-2-a-2","value":16},{"answer":"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.","answer_id":"c-2-a-3","value":8},{"answer":"This contribution adds no value to the open source community and ecosystem or the specific project.","answer_id":"c-2-a-4","value":0}]}]}}
Transaction InfoBlock #22059842/Trx 03dde85512c1586e98f170e71790007f979ab335
View Raw JSON Data
{
  "trx_id": "03dde85512c1586e98f170e71790007f979ab335",
  "block": 22059842,
  "trx_in_block": 37,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T21:52:45",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "title": "Advance Ruby Development Episode-1",
      "body": "#### Welcome to the First Tutorial of Advance Ruby Development\n<center> <img src= https://imgur.com/MILXLd2.jpg/> </center>\n\n#### What Will I Learn?\n\n- You will learn how to develop Applications using Ruby \n- You will learn about IRB shell in Ruby programming \n- You will learn about various class methods and their usage\n- Your will learn about reading and writing through class methods\n\n\n\n#### Requirements\n##### System Requirements:\n\n- [Ruby Installer]( https://www.ruby-lang.org/en/downloads/) for building apps\n- [SciTE]( https://www.scintilla.org/ScintillaDownload.html) for code editing \n- Command Prompt or Terminal \n##### OS Support:\n\n- Windows 7/8/10\n- macOS \n- Linux \n#### Difficulty\n\n\n\n- Intermediate\n\n#### Required Understanding\n- You just need a little bit of knowledge basic Ruby Syntax\n- A fair understanding of Programming \n- A thirst for learning and developing something new\n\n\n#### Description\n-\tIn this Advance Ruby Development course, I will teach you the advanced concepts of the Ruby programming language. Ruby was designed to be more powerful that Perl, and more object-oriented than Python, and has gained in popularity due to its power and ease of use. By the end of this course you will surely develop some powerful and concrete applications. Also in the end of this course we will be developing a Restaurant finder app.\n\n#### What is Ruby?\n\n\nRuby is an object-oriented, general purpose programming language designed by Yukihiro Matsumoto in the 1990s. Intended for improved productivity and entertaining, it creates a great starter language for first time programmers because of its simplicity, readability and concentrate on fun. Commonly used with Rails applications, that is a very popular language that is always in popularity. Organizations such as Twitter and Kickstarter utilize Ruby. \n\n With Ruby, almost everything is an object. Every bit of information as well as codes can be provided their very own attributes and actions. Object-oriented programming calls attributes by the title instance variables and also actions tend to be known as methods. Ruby’s genuine object-oriented approach is quite commonly demonstrated with a bit of code that is applicable an action to a number.\n```\n7.times { print \"I *like* Open Source Projects\" }\n\n```\nAs an example, addition is conducted with the `plus (+)` operator. However, if you would instead use the readable word `plus`, you can add this type of method to Ruby’s builtin Numeric class.\n```\nclass Numeric\n  def plus(x)\n    self.+(x)\n  end\nend\n\ny = 4.plus 3\n\n```\n`which results in the value of y=7\n`\n\n#### What is Interactive Ruby Shell (IRB) ?\n\n\nInteractive Ruby Shell (IRB ) is actually a REPL with regard to coding in the Ruby Language. Typically the abbreviation irb originates from the point that the filename extension for Ruby is **.rb**, even though interactive Ruby files don’t have an extension involving **.irb**.\n\nThe program will be launched from the command line and enables the execution of Ruby commands with immediate response, testing in real-time. This features command record, line modifying capabilities, and job control, and it is capable of communicate directly being a shell script on the internet and also connect to a live server.\n`irb [ options ] [ programfile ] [ argument... ] `\n##### Example:\n```\nirb(main):001:0> num = 4\n=> 4\nirb(main):002:0> def fact(num)\nirb(main):003:1>   if num <= 1\nirb(main):004:2>     1\nirb(main):005:2>   else\nirb(main):006:2*     num * fact(num - 1)\nirb(main):007:2>   end\nirb(main):008:1> end\n=> :fact\nirb(main):009:0> fact(num)\n=> 24\n```\n\n\nMethods In Ruby Programming\nRuby uses methods to use a block of codes. In other programming languages some other techniques are used like functions and procedures. Now we will have al look at methods in ruby and then we proceed to the next level.\n\n**Let have a look at this example**\n\n```\ndef course\n\tputs \"This course is about Ruby Programming \"\nend\n\ndef sub\n\tputs 7-3\nend\n\n# Underscore can be used between words, like variable names in this case\ndef longest_word\n  words = ['pineapple', 'orange', 'mango', 'watermelon']\n  longest_word = words.inject do |memo,word|\n    memo.length > word.length ? memo : word\n  end\n  puts longest_word\nend\n\n# Useful for tests and Booleans values\ndef greater_seven?\n\tvalue = 7\n\tputs value > 7 ? 'More than 7' : 'Less than 7'\nend\n```\nIn the above example I define four methods which are `course,sub,longest_word and greater_seven`\nBehaviour:\n\n`course`: It simply displays a message on the screen which is in this case is “This course is about Ruby Programming ”\n\n`sub`:This method simply perform the subtraction of two number which is passed as arguments  which are 7 and 3\n\n`longest_word`: This method does a little interesting job here,it returns me the longest word out of an array of four words by using the `inject` function which accumulates and returns the longest length word by increment the memo each time.\n\n`greater_seven?`: This methods basically testing which number is greater between the two and returns the Boolean value. It uses `?`at its end\n\n#### Reading and Writing Operations:\n\nRuby has methods for Reading and Writing known as Reader and Writer. Other languages have getters and setter for this reading/writing in programs. These methods will allow us to read data from a program or write data to it. Later these operations will help us in making our restaurant finder app. \n#### Example:\n```\nclass Person\n  def set_noise(noise)\n    @noise = noise\n  end\n  \n  def make_noise\n    @noise\n  end\nend\n\nperson_one = Person.new\nperson_one.set_noise(\"Laugh!\")\nputs person_one.make_noise\n\nperson_two = Person.new\nperson_two.set_noise(\"Groan!\")\nputs person_two.make_noise\n\n```\nNow this is a very common feature of object-oriented programming languages, sometimes in other languages, they're called getter and setter methods. Either one is fine. You can use either name, typically in Ruby, we're going to call them reader and writer methods. So, here is the code which is a perfect example to explain, what we're looking for is a pairing of something that will set a value for us and something that will get a value for us, and that's exactly what we already have with our two methods\n\nThe first one is a setter method or a writer method. So we're setting the value of noise equal to a value, and this is the classic format for what a setter method would look like.\n\n `set_noise` equal to a value. It sets it for us. Then we have a  `get_noise`. It's a getter method. The idea is that we are getting that value back. One of these methods sets it, one of them gets it.\nNow the important thing about these two methods is that they give us access control over these instance variables. So for **example**:\n```\nclass Person\n  def set_noise(noise)\n    @noise = noise\n  end\n  \nperson_one = Person.new\nperson_one.set_noise(\"Laugh!\")\nputs person_one.make_noise\n\nperson_two = Person.new\nperson_two.set_noise(\"Groan!\")\nputs person_two.make_noise\n```\nif we were to take away `get_noise`, now we have no way to get that value back. Of course, we could write another method that would do it for us, but our getter method is gone\n```\nclass Person\n  \n  def make_noise\n    @noise\n  end\nend\n\nperson_one = Person.new\nperson_one.set_noise(\"Laugh!\")\nputs person_one.make_noise\n\nperson_two = Person.new\nperson_two.set_noise(\"Groan!\")\nputs person_two.make_noise\n```\nSame thing here, if we were to take away `set_noise`, now we have no way to set it by calling a method. we need a setter method if we want to be able to do it directly.\n\nLike `set_noise` and `get_noise` and using underscore writing approach is very common in a lot of programming languages. In Ruby though, we can make use of that syntactic sugar that we looked at earlier, and so we can take get _out and simply ask for noise. So it asks Person to do the method noise, which returns the instance variable, noise. It's a very commonsense approach. \n```\nclass Person\n  def noise=(noise)\n    @noise = noise\n  end\n  \n  def noise\n    @noise\n  end\nend\n\nperson_one = Person.new\nperson_one.noise = \"Laugh!\"\nputs person_one.noise\n\nperson_two = Person.new\nperson_two.noise = \"Groan!\"\nputs person_two.noise\n```\nSo now` person_one.noise` and `person_two.noise` just returns that to us, where the syntactic sugar comes in is that we can do the same thing with set, we can take away set and just say `noise=(noise).`\n#### Summary\nIn this tutorial of Advance Ruby Development we learn about the methods, also now we have a better understanding of reading and writing using methods in Ruby. In the next tutorial we will learn about modules and development of our Restaurant Finder App.\n",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":538746,\"name\":\"ruby\",\"full_name\":\"ruby/ruby\",\"html_url\":\"https://github.com/ruby/ruby\",\"fork\":false,\"owner\":{\"login\":\"ruby\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"ruby\",\"app\",\"development\",\"utopian-io\"],\"users\":[\"noise\"],\"moderator\":{\"account\":\"portugalcoin\",\"time\":\"2018-05-01T21:52:46.827Z\",\"pending\":false,\"reviewed\":false,\"flagged\":true},\"questions\":{\"voters\":[\"engr-muneeb\"],\"answers\":[{\"question_id\":\"tuts-1\",\"answer_id\":\"tuts-1-a-2\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"tuts-2\",\"answer_id\":\"tuts-2-a-1\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"tuts-3\",\"answer_id\":\"tuts-3-a-2\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"tuts-4\",\"answer_id\":\"tuts-4-a-2\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"tuts-5\",\"answer_id\":\"tuts-5-a-1\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"tuts-6\",\"answer_id\":\"tuts-6-a-1\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"c-1\",\"answer_id\":\"c-1-a-1\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"c-2\",\"answer_id\":\"c-2-a-1\",\"user\":\"engr-muneeb\",\"influence\":0}],\"total_influence\":0,\"most_rated\":[{\"question_id\":\"tuts-1\",\"answer_id\":\"tuts-1-a-1\",\"influence\":0,\"voters\":[]},{\"question_id\":\"tuts-2\",\"answer_id\":\"tuts-2-a-1\",\"influence\":0,\"voters\":[\"engr-muneeb\"]},{\"question_id\":\"tuts-3\",\"answer_id\":\"tuts-3-a-1\",\"influence\":0,\"voters\":[]},{\"question_id\":\"tuts-4\",\"answer_id\":\"tuts-4-a-1\",\"influence\":0,\"voters\":[]},{\"question_id\":\"tuts-5\",\"answer_id\":\"tuts-5-a-1\",\"influence\":0,\"voters\":[\"engr-muneeb\"]},{\"question_id\":\"tuts-6\",\"answer_id\":\"tuts-6-a-1\",\"influence\":0,\"voters\":[\"engr-muneeb\"]},{\"question_id\":\"c-1\",\"answer_id\":\"c-1-a-1\",\"influence\":0,\"voters\":[\"engr-muneeb\"]},{\"question_id\":\"c-2\",\"answer_id\":\"c-2-a-1\",\"influence\":0,\"voters\":[\"engr-muneeb\"]}]},\"score\":100,\"total_influence\":0,\"staff_pick\":null,\"staff_pick_by\":null,\"config\":{\"questions\":[{\"question\":\"How many substantial concepts does this tutorial address?\",\"question_id\":\"tuts-1\",\"answers\":[{\"answer\":\"4-5 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-1\",\"value\":10},{\"answer\":\"2-3 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-2\",\"value\":7},{\"answer\":\"1 substantial concept covered in the tutorial.\",\"answer_id\":\"tuts-1-a-3\",\"value\":3},{\"answer\":\"More than 5 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-4\",\"value\":0}]},{\"question\":\"Does the title and the outline of the tutorial properly reflect the content?\",\"question_id\":\"tuts-2\",\"answers\":[{\"answer\":\"Yes, it is very clear.\",\"answer_id\":\"tuts-2-a-1\",\"value\":15},{\"answer\":\"To some extent.\",\"answer_id\":\"tuts-2-a-2\",\"value\":11.5},{\"answer\":\"The title is somewhat misleading and/or the outline is not detailed or informative enough.\",\"answer_id\":\"tuts-2-a-3\",\"value\":4.5},{\"answer\":\"Title and outline are of little or no relevance to the content of the tutorial.\",\"answer_id\":\"tuts-2-a-4\",\"value\":0}]},{\"question\":\"Did the contributor provide supplementary resources, such as code and sample files in the contribution post or a linked GitHub repository?\",\"question_id\":\"tuts-3\",\"answers\":[{\"answer\":\"Yes, exceptional supplementary resources are provided including a relevant github repo/gist.\",\"answer_id\":\"tuts-3-a-1\",\"value\":15},{\"answer\":\"Supplementary resources provided are of high relevance.\",\"answer_id\":\"tuts-3-a-2\",\"value\":12},{\"answer\":\"Contributor provides minimal supplementary resources.\",\"answer_id\":\"tuts-3-a-3\",\"value\":6},{\"answer\":\"No supplementary resources were provided.\",\"answer_id\":\"tuts-3-a-4\",\"value\":0}]},{\"question\":\"Is the tutorial part of a series?\",\"question_id\":\"tuts-4\",\"answers\":[{\"answer\":\"Yes.\",\"answer_id\":\"tuts-4-a-1\",\"value\":10},{\"answer\":\"Yes, but it is the first entry in the series.\",\"answer_id\":\"tuts-4-a-2\",\"value\":7},{\"answer\":\"No, but it works just fine as a stand-alone tutorial.\",\"answer_id\":\"tuts-4-a-3\",\"value\":5},{\"answer\":\"No.\",\"answer_id\":\"tuts-4-a-4\",\"value\":0}]},{\"question\":\"Does the tutorial contain sufficient explanatory visuals?\",\"question_id\":\"tuts-5\",\"answers\":[{\"answer\":\"Yes, the visual components of the post were adequate in quality and quantity.\",\"answer_id\":\"tuts-5-a-1\",\"value\":10},{\"answer\":\"The volume of visual components included was unnecessarily large.\",\"answer_id\":\"tuts-5-a-2\",\"value\":7},{\"answer\":\"The post lacked sufficient visualization to easily learn from the content.\",\"answer_id\":\"tuts-5-a-3\",\"value\":3},{\"answer\":\"No visualization was presented in this contribution.\",\"answer_id\":\"tuts-5-a-4\",\"value\":0}]},{\"question\":\"How unique and/or innovative are the concepts covered in the tutorial?\",\"question_id\":\"tuts-6\",\"answers\":[{\"answer\":\"This was the first time I read about the concepts covered.\",\"answer_id\":\"tuts-6-a-1\",\"value\":10},{\"answer\":\"The concepts covered were innovative and offer some usefulness.\",\"answer_id\":\"tuts-6-a-2\",\"value\":7},{\"answer\":\"I have read several similar ideas and thoughts elsewhere, but this one was of higher quality.\",\"answer_id\":\"tuts-6-a-3\",\"value\":5},{\"answer\":\"Such tutorials can be found online with great ease and the contribution add no value to the open source community.\",\"answer_id\":\"tuts-6-a-4\",\"value\":0}]},{\"question\":\"How would you describe the formatting, language and overall presentation of the post?\",\"question_id\":\"c-1\",\"answers\":[{\"answer\":\"The post is of very high quality.\",\"answer_id\":\"c-1-a-1\",\"value\":10},{\"answer\":\"The post is of decent quality, but not spectacular in any way.\",\"answer_id\":\"c-1-a-2\",\"value\":7},{\"answer\":\"The post is poorly written and/or formatted, but readable.\",\"answer_id\":\"c-1-a-3\",\"value\":3},{\"answer\":\"The post is really hard to read and the content is barely understandable.\",\"answer_id\":\"c-1-a-4\",\"value\":0}]},{\"question\":\"How would you rate the overall value of this contribution on the open source community and ecosystem?\",\"question_id\":\"c-2\",\"answers\":[{\"answer\":\"This contribution brings great and impactful value, and can be used for applications outside the specific project.\",\"answer_id\":\"c-2-a-1\",\"value\":20},{\"answer\":\"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.\",\"answer_id\":\"c-2-a-2\",\"value\":16},{\"answer\":\"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.\",\"answer_id\":\"c-2-a-3\",\"value\":8},{\"answer\":\"This contribution adds no value to the open source community and ecosystem or the specific project.\",\"answer_id\":\"c-2-a-4\",\"value\":0}]}]}}"
    }
  ]
}
2018/05/01 21:52:03
parent author
parent permlinkutopian-io
authorexploringworld
permlinkadvance-ruby-development-episode-1
titleAdvance Ruby Development Episode-1
body#### Welcome to the First Tutorial of Advance Ruby Development <center> <img src= https://imgur.com/MILXLd2.jpg/> </center> #### What Will I Learn? - You will learn how to develop Applications using Ruby - You will learn about IRB shell in Ruby programming - You will learn about various class methods and their usage - Your will learn about reading and writing through class methods #### Requirements ##### System Requirements: - [Ruby Installer]( https://www.ruby-lang.org/en/downloads/) for building apps - [SciTE]( https://www.scintilla.org/ScintillaDownload.html) for code editing - Command Prompt or Terminal ##### OS Support: - Windows 7/8/10 - macOS - Linux #### Difficulty - Intermediate #### Required Understanding - You just need a little bit of knowledge basic Ruby Syntax - A fair understanding of Programming - A thirst for learning and developing something new #### Description - In this Advance Ruby Development course, I will teach you the advanced concepts of the Ruby programming language. Ruby was designed to be more powerful that Perl, and more object-oriented than Python, and has gained in popularity due to its power and ease of use. By the end of this course you will surely develop some powerful and concrete applications. Also in the end of this course we will be developing a Restaurant finder app. #### What is Ruby? Ruby is an object-oriented, general purpose programming language designed by Yukihiro Matsumoto in the 1990s. Intended for improved productivity and entertaining, it creates a great starter language for first time programmers because of its simplicity, readability and concentrate on fun. Commonly used with Rails applications, that is a very popular language that is always in popularity. Organizations such as Twitter and Kickstarter utilize Ruby. With Ruby, almost everything is an object. Every bit of information as well as codes can be provided their very own attributes and actions. Object-oriented programming calls attributes by the title instance variables and also actions tend to be known as methods. Ruby’s genuine object-oriented approach is quite commonly demonstrated with a bit of code that is applicable an action to a number. ``` 7.times { print "I *like* Open Source Projects" } ``` As an example, addition is conducted with the `plus (+)` operator. However, if you would instead use the readable word `plus`, you can add this type of method to Ruby’s builtin Numeric class. ``` class Numeric def plus(x) self.+(x) end end y = 4.plus 3 ``` `which results in the value of y=7 ` #### What is Interactive Ruby Shell (IRB) ? Interactive Ruby Shell (IRB ) is actually a REPL with regard to coding in the Ruby Language. Typically the abbreviation irb originates from the point that the filename extension for Ruby is **.rb**, even though interactive Ruby files don’t have an extension involving **.irb**. The program will be launched from the command line and enables the execution of Ruby commands with immediate response, testing in real-time. This features command record, line modifying capabilities, and job control, and it is capable of communicate directly being a shell script on the internet and also connect to a live server. `irb [ options ] [ programfile ] [ argument... ] ` ##### Example: ``` irb(main):001:0> num = 4 => 4 irb(main):002:0> def fact(num) irb(main):003:1> if num <= 1 irb(main):004:2> 1 irb(main):005:2> else irb(main):006:2* num * fact(num - 1) irb(main):007:2> end irb(main):008:1> end => :fact irb(main):009:0> fact(num) => 24 ``` Methods In Ruby Programming Ruby uses methods to use a block of codes. In other programming languages some other techniques are used like functions and procedures. Now we will have al look at methods in ruby and then we proceed to the next level. **Let have a look at this example** ``` def course puts "This course is about Ruby Programming " end def sub puts 7-3 end # Underscore can be used between words, like variable names in this case def longest_word words = ['pineapple', 'orange', 'mango', 'watermelon'] longest_word = words.inject do |memo,word| memo.length > word.length ? memo : word end puts longest_word end # Useful for tests and Booleans values def greater_seven? value = 7 puts value > 7 ? 'More than 7' : 'Less than 7' end ``` In the above example I define four methods which are `course,sub,longest_word and greater_seven` Behaviour: `course`: It simply displays a message on the screen which is in this case is “This course is about Ruby Programming ” `sub`:This method simply perform the subtraction of two number which is passed as arguments which are 7 and 3 `longest_word`: This method does a little interesting job here,it returns me the longest word out of an array of four words by using the `inject` function which accumulates and returns the longest length word by increment the memo each time. `greater_seven?`: This methods basically testing which number is greater between the two and returns the Boolean value. It uses `?`at its end #### Reading and Writing Operations: Ruby has methods for Reading and Writing known as Reader and Writer. Other languages have getters and setter for this reading/writing in programs. These methods will allow us to read data from a program or write data to it. Later these operations will help us in making our restaurant finder app. #### Example: ``` class Person def set_noise(noise) @noise = noise end def make_noise @noise end end person_one = Person.new person_one.set_noise("Laugh!") puts person_one.make_noise person_two = Person.new person_two.set_noise("Groan!") puts person_two.make_noise ``` Now this is a very common feature of object-oriented programming languages, sometimes in other languages, they're called getter and setter methods. Either one is fine. You can use either name, typically in Ruby, we're going to call them reader and writer methods. So, here is the code which is a perfect example to explain, what we're looking for is a pairing of something that will set a value for us and something that will get a value for us, and that's exactly what we already have with our two methods The first one is a setter method or a writer method. So we're setting the value of noise equal to a value, and this is the classic format for what a setter method would look like. `set_noise` equal to a value. It sets it for us. Then we have a `get_noise`. It's a getter method. The idea is that we are getting that value back. One of these methods sets it, one of them gets it. Now the important thing about these two methods is that they give us access control over these instance variables. So for **example**: ``` class Person def set_noise(noise) @noise = noise end person_one = Person.new person_one.set_noise("Laugh!") puts person_one.make_noise person_two = Person.new person_two.set_noise("Groan!") puts person_two.make_noise ``` if we were to take away `get_noise`, now we have no way to get that value back. Of course, we could write another method that would do it for us, but our getter method is gone ``` class Person def make_noise @noise end end person_one = Person.new person_one.set_noise("Laugh!") puts person_one.make_noise person_two = Person.new person_two.set_noise("Groan!") puts person_two.make_noise ``` Same thing here, if we were to take away `set_noise`, now we have no way to set it by calling a method. we need a setter method if we want to be able to do it directly. Like `set_noise` and `get_noise` and using underscore writing approach is very common in a lot of programming languages. In Ruby though, we can make use of that syntactic sugar that we looked at earlier, and so we can take get _out and simply ask for noise. So it asks Person to do the method noise, which returns the instance variable, noise. It's a very commonsense approach. ``` class Person def noise=(noise) @noise = noise end def noise @noise end end person_one = Person.new person_one.noise = "Laugh!" puts person_one.noise person_two = Person.new person_two.noise = "Groan!" puts person_two.noise ``` So now` person_one.noise` and `person_two.noise` just returns that to us, where the syntactic sugar comes in is that we can do the same thing with set, we can take away set and just say `noise=(noise).` #### Summary In this tutorial of Advance Ruby Development we learn about the methods, also now we have a better understanding of reading and writing using methods in Ruby. In the next tutorial we will learn about modules and development of our Restaurant Finder App.
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":538746,"name":"ruby","full_name":"ruby/ruby","html_url":"https://github.com/ruby/ruby","fork":false,"owner":{"login":"ruby"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","ruby","app","development","utopian-io"],"users":["noise"],"moderator":{"account":"portugalcoin","time":"2018-05-01T21:52:03.993Z","pending":true,"reviewed":false,"flagged":false},"questions":{"voters":["engr-muneeb"],"answers":[{"question_id":"tuts-1","answer_id":"tuts-1-a-2","user":"engr-muneeb","influence":0},{"question_id":"tuts-2","answer_id":"tuts-2-a-1","user":"engr-muneeb","influence":0},{"question_id":"tuts-3","answer_id":"tuts-3-a-2","user":"engr-muneeb","influence":0},{"question_id":"tuts-4","answer_id":"tuts-4-a-2","user":"engr-muneeb","influence":0},{"question_id":"tuts-5","answer_id":"tuts-5-a-1","user":"engr-muneeb","influence":0},{"question_id":"tuts-6","answer_id":"tuts-6-a-1","user":"engr-muneeb","influence":0},{"question_id":"c-1","answer_id":"c-1-a-1","user":"engr-muneeb","influence":0},{"question_id":"c-2","answer_id":"c-2-a-1","user":"engr-muneeb","influence":0}],"total_influence":0,"most_rated":[{"question_id":"tuts-1","answer_id":"tuts-1-a-1","influence":0,"voters":[]},{"question_id":"tuts-2","answer_id":"tuts-2-a-1","influence":0,"voters":["engr-muneeb"]},{"question_id":"tuts-3","answer_id":"tuts-3-a-1","influence":0,"voters":[]},{"question_id":"tuts-4","answer_id":"tuts-4-a-1","influence":0,"voters":[]},{"question_id":"tuts-5","answer_id":"tuts-5-a-1","influence":0,"voters":["engr-muneeb"]},{"question_id":"tuts-6","answer_id":"tuts-6-a-1","influence":0,"voters":["engr-muneeb"]},{"question_id":"c-1","answer_id":"c-1-a-1","influence":0,"voters":["engr-muneeb"]},{"question_id":"c-2","answer_id":"c-2-a-1","influence":0,"voters":["engr-muneeb"]}]},"score":100,"total_influence":0,"staff_pick":null,"staff_pick_by":null,"config":{"questions":[{"question":"How many substantial concepts does this tutorial address?","question_id":"tuts-1","answers":[{"answer":"4-5 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-1","value":10},{"answer":"2-3 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-2","value":7},{"answer":"1 substantial concept covered in the tutorial.","answer_id":"tuts-1-a-3","value":3},{"answer":"More than 5 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-4","value":0}]},{"question":"Does the title and the outline of the tutorial properly reflect the content?","question_id":"tuts-2","answers":[{"answer":"Yes, it is very clear.","answer_id":"tuts-2-a-1","value":15},{"answer":"To some extent.","answer_id":"tuts-2-a-2","value":11.5},{"answer":"The title is somewhat misleading and/or the outline is not detailed or informative enough.","answer_id":"tuts-2-a-3","value":4.5},{"answer":"Title and outline are of little or no relevance to the content of the tutorial.","answer_id":"tuts-2-a-4","value":0}]},{"question":"Did the contributor provide supplementary resources, such as code and sample files in the contribution post or a linked GitHub repository?","question_id":"tuts-3","answers":[{"answer":"Yes, exceptional supplementary resources are provided including a relevant github repo/gist.","answer_id":"tuts-3-a-1","value":15},{"answer":"Supplementary resources provided are of high relevance.","answer_id":"tuts-3-a-2","value":12},{"answer":"Contributor provides minimal supplementary resources.","answer_id":"tuts-3-a-3","value":6},{"answer":"No supplementary resources were provided.","answer_id":"tuts-3-a-4","value":0}]},{"question":"Is the tutorial part of a series?","question_id":"tuts-4","answers":[{"answer":"Yes.","answer_id":"tuts-4-a-1","value":10},{"answer":"Yes, but it is the first entry in the series.","answer_id":"tuts-4-a-2","value":7},{"answer":"No, but it works just fine as a stand-alone tutorial.","answer_id":"tuts-4-a-3","value":5},{"answer":"No.","answer_id":"tuts-4-a-4","value":0}]},{"question":"Does the tutorial contain sufficient explanatory visuals?","question_id":"tuts-5","answers":[{"answer":"Yes, the visual components of the post were adequate in quality and quantity.","answer_id":"tuts-5-a-1","value":10},{"answer":"The volume of visual components included was unnecessarily large.","answer_id":"tuts-5-a-2","value":7},{"answer":"The post lacked sufficient visualization to easily learn from the content.","answer_id":"tuts-5-a-3","value":3},{"answer":"No visualization was presented in this contribution.","answer_id":"tuts-5-a-4","value":0}]},{"question":"How unique and/or innovative are the concepts covered in the tutorial?","question_id":"tuts-6","answers":[{"answer":"This was the first time I read about the concepts covered.","answer_id":"tuts-6-a-1","value":10},{"answer":"The concepts covered were innovative and offer some usefulness.","answer_id":"tuts-6-a-2","value":7},{"answer":"I have read several similar ideas and thoughts elsewhere, but this one was of higher quality.","answer_id":"tuts-6-a-3","value":5},{"answer":"Such tutorials can be found online with great ease and the contribution add no value to the open source community.","answer_id":"tuts-6-a-4","value":0}]},{"question":"How would you describe the formatting, language and overall presentation of the post?","question_id":"c-1","answers":[{"answer":"The post is of very high quality.","answer_id":"c-1-a-1","value":10},{"answer":"The post is of decent quality, but not spectacular in any way.","answer_id":"c-1-a-2","value":7},{"answer":"The post is poorly written and/or formatted, but readable.","answer_id":"c-1-a-3","value":3},{"answer":"The post is really hard to read and the content is barely understandable.","answer_id":"c-1-a-4","value":0}]},{"question":"How would you rate the overall value of this contribution on the open source community and ecosystem?","question_id":"c-2","answers":[{"answer":"This contribution brings great and impactful value, and can be used for applications outside the specific project.","answer_id":"c-2-a-1","value":20},{"answer":"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.","answer_id":"c-2-a-2","value":16},{"answer":"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.","answer_id":"c-2-a-3","value":8},{"answer":"This contribution adds no value to the open source community and ecosystem or the specific project.","answer_id":"c-2-a-4","value":0}]}]}}
Transaction InfoBlock #22059828/Trx 82b7138c80c914cd874e8cd168d340466dffa85e
View Raw JSON Data
{
  "trx_id": "82b7138c80c914cd874e8cd168d340466dffa85e",
  "block": 22059828,
  "trx_in_block": 20,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T21:52:03",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "title": "Advance Ruby Development Episode-1",
      "body": "#### Welcome to the First Tutorial of Advance Ruby Development\n<center> <img src= https://imgur.com/MILXLd2.jpg/> </center>\n\n#### What Will I Learn?\n\n- You will learn how to develop Applications using Ruby \n- You will learn about IRB shell in Ruby programming \n- You will learn about various class methods and their usage\n- Your will learn about reading and writing through class methods\n\n\n\n#### Requirements\n##### System Requirements:\n\n- [Ruby Installer]( https://www.ruby-lang.org/en/downloads/) for building apps\n- [SciTE]( https://www.scintilla.org/ScintillaDownload.html) for code editing \n- Command Prompt or Terminal \n##### OS Support:\n\n- Windows 7/8/10\n- macOS \n- Linux \n#### Difficulty\n\n\n\n- Intermediate\n\n#### Required Understanding\n- You just need a little bit of knowledge basic Ruby Syntax\n- A fair understanding of Programming \n- A thirst for learning and developing something new\n\n\n#### Description\n-\tIn this Advance Ruby Development course, I will teach you the advanced concepts of the Ruby programming language. Ruby was designed to be more powerful that Perl, and more object-oriented than Python, and has gained in popularity due to its power and ease of use. By the end of this course you will surely develop some powerful and concrete applications. Also in the end of this course we will be developing a Restaurant finder app.\n\n#### What is Ruby?\n\n\nRuby is an object-oriented, general purpose programming language designed by Yukihiro Matsumoto in the 1990s. Intended for improved productivity and entertaining, it creates a great starter language for first time programmers because of its simplicity, readability and concentrate on fun. Commonly used with Rails applications, that is a very popular language that is always in popularity. Organizations such as Twitter and Kickstarter utilize Ruby. \n\n With Ruby, almost everything is an object. Every bit of information as well as codes can be provided their very own attributes and actions. Object-oriented programming calls attributes by the title instance variables and also actions tend to be known as methods. Ruby’s genuine object-oriented approach is quite commonly demonstrated with a bit of code that is applicable an action to a number.\n```\n7.times { print \"I *like* Open Source Projects\" }\n\n```\nAs an example, addition is conducted with the `plus (+)` operator. However, if you would instead use the readable word `plus`, you can add this type of method to Ruby’s builtin Numeric class.\n```\nclass Numeric\n  def plus(x)\n    self.+(x)\n  end\nend\n\ny = 4.plus 3\n\n```\n`which results in the value of y=7\n`\n\n#### What is Interactive Ruby Shell (IRB) ?\n\n\nInteractive Ruby Shell (IRB ) is actually a REPL with regard to coding in the Ruby Language. Typically the abbreviation irb originates from the point that the filename extension for Ruby is **.rb**, even though interactive Ruby files don’t have an extension involving **.irb**.\n\nThe program will be launched from the command line and enables the execution of Ruby commands with immediate response, testing in real-time. This features command record, line modifying capabilities, and job control, and it is capable of communicate directly being a shell script on the internet and also connect to a live server.\n`irb [ options ] [ programfile ] [ argument... ] `\n##### Example:\n```\nirb(main):001:0> num = 4\n=> 4\nirb(main):002:0> def fact(num)\nirb(main):003:1>   if num <= 1\nirb(main):004:2>     1\nirb(main):005:2>   else\nirb(main):006:2*     num * fact(num - 1)\nirb(main):007:2>   end\nirb(main):008:1> end\n=> :fact\nirb(main):009:0> fact(num)\n=> 24\n```\n\n\nMethods In Ruby Programming\nRuby uses methods to use a block of codes. In other programming languages some other techniques are used like functions and procedures. Now we will have al look at methods in ruby and then we proceed to the next level.\n\n**Let have a look at this example**\n\n```\ndef course\n\tputs \"This course is about Ruby Programming \"\nend\n\ndef sub\n\tputs 7-3\nend\n\n# Underscore can be used between words, like variable names in this case\ndef longest_word\n  words = ['pineapple', 'orange', 'mango', 'watermelon']\n  longest_word = words.inject do |memo,word|\n    memo.length > word.length ? memo : word\n  end\n  puts longest_word\nend\n\n# Useful for tests and Booleans values\ndef greater_seven?\n\tvalue = 7\n\tputs value > 7 ? 'More than 7' : 'Less than 7'\nend\n```\nIn the above example I define four methods which are `course,sub,longest_word and greater_seven`\nBehaviour:\n\n`course`: It simply displays a message on the screen which is in this case is “This course is about Ruby Programming ”\n\n`sub`:This method simply perform the subtraction of two number which is passed as arguments  which are 7 and 3\n\n`longest_word`: This method does a little interesting job here,it returns me the longest word out of an array of four words by using the `inject` function which accumulates and returns the longest length word by increment the memo each time.\n\n`greater_seven?`: This methods basically testing which number is greater between the two and returns the Boolean value. It uses `?`at its end\n\n#### Reading and Writing Operations:\n\nRuby has methods for Reading and Writing known as Reader and Writer. Other languages have getters and setter for this reading/writing in programs. These methods will allow us to read data from a program or write data to it. Later these operations will help us in making our restaurant finder app. \n#### Example:\n```\nclass Person\n  def set_noise(noise)\n    @noise = noise\n  end\n  \n  def make_noise\n    @noise\n  end\nend\n\nperson_one = Person.new\nperson_one.set_noise(\"Laugh!\")\nputs person_one.make_noise\n\nperson_two = Person.new\nperson_two.set_noise(\"Groan!\")\nputs person_two.make_noise\n\n```\nNow this is a very common feature of object-oriented programming languages, sometimes in other languages, they're called getter and setter methods. Either one is fine. You can use either name, typically in Ruby, we're going to call them reader and writer methods. So, here is the code which is a perfect example to explain, what we're looking for is a pairing of something that will set a value for us and something that will get a value for us, and that's exactly what we already have with our two methods\n\nThe first one is a setter method or a writer method. So we're setting the value of noise equal to a value, and this is the classic format for what a setter method would look like.\n\n `set_noise` equal to a value. It sets it for us. Then we have a  `get_noise`. It's a getter method. The idea is that we are getting that value back. One of these methods sets it, one of them gets it.\nNow the important thing about these two methods is that they give us access control over these instance variables. So for **example**:\n```\nclass Person\n  def set_noise(noise)\n    @noise = noise\n  end\n  \nperson_one = Person.new\nperson_one.set_noise(\"Laugh!\")\nputs person_one.make_noise\n\nperson_two = Person.new\nperson_two.set_noise(\"Groan!\")\nputs person_two.make_noise\n```\nif we were to take away `get_noise`, now we have no way to get that value back. Of course, we could write another method that would do it for us, but our getter method is gone\n```\nclass Person\n  \n  def make_noise\n    @noise\n  end\nend\n\nperson_one = Person.new\nperson_one.set_noise(\"Laugh!\")\nputs person_one.make_noise\n\nperson_two = Person.new\nperson_two.set_noise(\"Groan!\")\nputs person_two.make_noise\n```\nSame thing here, if we were to take away `set_noise`, now we have no way to set it by calling a method. we need a setter method if we want to be able to do it directly.\n\nLike `set_noise` and `get_noise` and using underscore writing approach is very common in a lot of programming languages. In Ruby though, we can make use of that syntactic sugar that we looked at earlier, and so we can take get _out and simply ask for noise. So it asks Person to do the method noise, which returns the instance variable, noise. It's a very commonsense approach. \n```\nclass Person\n  def noise=(noise)\n    @noise = noise\n  end\n  \n  def noise\n    @noise\n  end\nend\n\nperson_one = Person.new\nperson_one.noise = \"Laugh!\"\nputs person_one.noise\n\nperson_two = Person.new\nperson_two.noise = \"Groan!\"\nputs person_two.noise\n```\nSo now` person_one.noise` and `person_two.noise` just returns that to us, where the syntactic sugar comes in is that we can do the same thing with set, we can take away set and just say `noise=(noise).`\n#### Summary\nIn this tutorial of Advance Ruby Development we learn about the methods, also now we have a better understanding of reading and writing using methods in Ruby. In the next tutorial we will learn about modules and development of our Restaurant Finder App.\n",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":538746,\"name\":\"ruby\",\"full_name\":\"ruby/ruby\",\"html_url\":\"https://github.com/ruby/ruby\",\"fork\":false,\"owner\":{\"login\":\"ruby\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"ruby\",\"app\",\"development\",\"utopian-io\"],\"users\":[\"noise\"],\"moderator\":{\"account\":\"portugalcoin\",\"time\":\"2018-05-01T21:52:03.993Z\",\"pending\":true,\"reviewed\":false,\"flagged\":false},\"questions\":{\"voters\":[\"engr-muneeb\"],\"answers\":[{\"question_id\":\"tuts-1\",\"answer_id\":\"tuts-1-a-2\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"tuts-2\",\"answer_id\":\"tuts-2-a-1\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"tuts-3\",\"answer_id\":\"tuts-3-a-2\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"tuts-4\",\"answer_id\":\"tuts-4-a-2\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"tuts-5\",\"answer_id\":\"tuts-5-a-1\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"tuts-6\",\"answer_id\":\"tuts-6-a-1\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"c-1\",\"answer_id\":\"c-1-a-1\",\"user\":\"engr-muneeb\",\"influence\":0},{\"question_id\":\"c-2\",\"answer_id\":\"c-2-a-1\",\"user\":\"engr-muneeb\",\"influence\":0}],\"total_influence\":0,\"most_rated\":[{\"question_id\":\"tuts-1\",\"answer_id\":\"tuts-1-a-1\",\"influence\":0,\"voters\":[]},{\"question_id\":\"tuts-2\",\"answer_id\":\"tuts-2-a-1\",\"influence\":0,\"voters\":[\"engr-muneeb\"]},{\"question_id\":\"tuts-3\",\"answer_id\":\"tuts-3-a-1\",\"influence\":0,\"voters\":[]},{\"question_id\":\"tuts-4\",\"answer_id\":\"tuts-4-a-1\",\"influence\":0,\"voters\":[]},{\"question_id\":\"tuts-5\",\"answer_id\":\"tuts-5-a-1\",\"influence\":0,\"voters\":[\"engr-muneeb\"]},{\"question_id\":\"tuts-6\",\"answer_id\":\"tuts-6-a-1\",\"influence\":0,\"voters\":[\"engr-muneeb\"]},{\"question_id\":\"c-1\",\"answer_id\":\"c-1-a-1\",\"influence\":0,\"voters\":[\"engr-muneeb\"]},{\"question_id\":\"c-2\",\"answer_id\":\"c-2-a-1\",\"influence\":0,\"voters\":[\"engr-muneeb\"]}]},\"score\":100,\"total_influence\":0,\"staff_pick\":null,\"staff_pick_by\":null,\"config\":{\"questions\":[{\"question\":\"How many substantial concepts does this tutorial address?\",\"question_id\":\"tuts-1\",\"answers\":[{\"answer\":\"4-5 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-1\",\"value\":10},{\"answer\":\"2-3 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-2\",\"value\":7},{\"answer\":\"1 substantial concept covered in the tutorial.\",\"answer_id\":\"tuts-1-a-3\",\"value\":3},{\"answer\":\"More than 5 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-4\",\"value\":0}]},{\"question\":\"Does the title and the outline of the tutorial properly reflect the content?\",\"question_id\":\"tuts-2\",\"answers\":[{\"answer\":\"Yes, it is very clear.\",\"answer_id\":\"tuts-2-a-1\",\"value\":15},{\"answer\":\"To some extent.\",\"answer_id\":\"tuts-2-a-2\",\"value\":11.5},{\"answer\":\"The title is somewhat misleading and/or the outline is not detailed or informative enough.\",\"answer_id\":\"tuts-2-a-3\",\"value\":4.5},{\"answer\":\"Title and outline are of little or no relevance to the content of the tutorial.\",\"answer_id\":\"tuts-2-a-4\",\"value\":0}]},{\"question\":\"Did the contributor provide supplementary resources, such as code and sample files in the contribution post or a linked GitHub repository?\",\"question_id\":\"tuts-3\",\"answers\":[{\"answer\":\"Yes, exceptional supplementary resources are provided including a relevant github repo/gist.\",\"answer_id\":\"tuts-3-a-1\",\"value\":15},{\"answer\":\"Supplementary resources provided are of high relevance.\",\"answer_id\":\"tuts-3-a-2\",\"value\":12},{\"answer\":\"Contributor provides minimal supplementary resources.\",\"answer_id\":\"tuts-3-a-3\",\"value\":6},{\"answer\":\"No supplementary resources were provided.\",\"answer_id\":\"tuts-3-a-4\",\"value\":0}]},{\"question\":\"Is the tutorial part of a series?\",\"question_id\":\"tuts-4\",\"answers\":[{\"answer\":\"Yes.\",\"answer_id\":\"tuts-4-a-1\",\"value\":10},{\"answer\":\"Yes, but it is the first entry in the series.\",\"answer_id\":\"tuts-4-a-2\",\"value\":7},{\"answer\":\"No, but it works just fine as a stand-alone tutorial.\",\"answer_id\":\"tuts-4-a-3\",\"value\":5},{\"answer\":\"No.\",\"answer_id\":\"tuts-4-a-4\",\"value\":0}]},{\"question\":\"Does the tutorial contain sufficient explanatory visuals?\",\"question_id\":\"tuts-5\",\"answers\":[{\"answer\":\"Yes, the visual components of the post were adequate in quality and quantity.\",\"answer_id\":\"tuts-5-a-1\",\"value\":10},{\"answer\":\"The volume of visual components included was unnecessarily large.\",\"answer_id\":\"tuts-5-a-2\",\"value\":7},{\"answer\":\"The post lacked sufficient visualization to easily learn from the content.\",\"answer_id\":\"tuts-5-a-3\",\"value\":3},{\"answer\":\"No visualization was presented in this contribution.\",\"answer_id\":\"tuts-5-a-4\",\"value\":0}]},{\"question\":\"How unique and/or innovative are the concepts covered in the tutorial?\",\"question_id\":\"tuts-6\",\"answers\":[{\"answer\":\"This was the first time I read about the concepts covered.\",\"answer_id\":\"tuts-6-a-1\",\"value\":10},{\"answer\":\"The concepts covered were innovative and offer some usefulness.\",\"answer_id\":\"tuts-6-a-2\",\"value\":7},{\"answer\":\"I have read several similar ideas and thoughts elsewhere, but this one was of higher quality.\",\"answer_id\":\"tuts-6-a-3\",\"value\":5},{\"answer\":\"Such tutorials can be found online with great ease and the contribution add no value to the open source community.\",\"answer_id\":\"tuts-6-a-4\",\"value\":0}]},{\"question\":\"How would you describe the formatting, language and overall presentation of the post?\",\"question_id\":\"c-1\",\"answers\":[{\"answer\":\"The post is of very high quality.\",\"answer_id\":\"c-1-a-1\",\"value\":10},{\"answer\":\"The post is of decent quality, but not spectacular in any way.\",\"answer_id\":\"c-1-a-2\",\"value\":7},{\"answer\":\"The post is poorly written and/or formatted, but readable.\",\"answer_id\":\"c-1-a-3\",\"value\":3},{\"answer\":\"The post is really hard to read and the content is barely understandable.\",\"answer_id\":\"c-1-a-4\",\"value\":0}]},{\"question\":\"How would you rate the overall value of this contribution on the open source community and ecosystem?\",\"question_id\":\"c-2\",\"answers\":[{\"answer\":\"This contribution brings great and impactful value, and can be used for applications outside the specific project.\",\"answer_id\":\"c-2-a-1\",\"value\":20},{\"answer\":\"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.\",\"answer_id\":\"c-2-a-2\",\"value\":16},{\"answer\":\"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.\",\"answer_id\":\"c-2-a-3\",\"value\":8},{\"answer\":\"This contribution adds no value to the open source community and ecosystem or the specific project.\",\"answer_id\":\"c-2-a-4\",\"value\":0}]}]}}"
    }
  ]
}
2018/05/01 21:01:30
parent author
parent permlinkutopian-io
authorexploringworld
permlinkadvance-ruby-development-episode-1
titleAdvance Ruby Development Episode-1
body@@ -4606,20 +4606,23 @@ orm the -addi +subtrac tion of
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":538746,"name":"ruby","full_name":"ruby/ruby","html_url":"https://github.com/ruby/ruby","fork":false,"owner":{"login":"ruby"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","ruby","app","development","utopian-io"],"users":["noise"]}
Transaction InfoBlock #22058817/Trx 1bcd912eeaf9ad9496427213fc0ec98469772eff
View Raw JSON Data
{
  "trx_id": "1bcd912eeaf9ad9496427213fc0ec98469772eff",
  "block": 22058817,
  "trx_in_block": 26,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T21:01:30",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "title": "Advance Ruby Development Episode-1",
      "body": "@@ -4606,20 +4606,23 @@\n orm the \n-addi\n+subtrac\n tion of \n",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":538746,\"name\":\"ruby\",\"full_name\":\"ruby/ruby\",\"html_url\":\"https://github.com/ruby/ruby\",\"fork\":false,\"owner\":{\"login\":\"ruby\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"ruby\",\"app\",\"development\",\"utopian-io\"],\"users\":[\"noise\"]}"
    }
  ]
}
2018/05/01 20:40:15
parent author
parent permlinkutopian-io
authorexploringworld
permlinkadvance-ruby-development-episode-1
titleAdvance Ruby Development Episode-1
body@@ -1361,16 +1361,18 @@ s Ruby?%0A +%0A%0A Ruby is @@ -1815,18 +1815,16 @@ Ruby. %0A%0A -%0A%0A With Ru @@ -2619,16 +2619,18 @@ (IRB) ?%0A +%0A%0A Interact @@ -3866,22 +3866,21 @@ %60%60%60%0Adef -welcom +cours e%0A%09puts @@ -3933,22 +3933,20 @@ def -add +sub %0A%09puts -2 + +7- 3%0Aen @@ -3961,16 +3961,28 @@ erscore +can be used between @@ -4007,16 +4007,29 @@ le names + in this case %0Adef lon @@ -4050,16 +4050,20 @@ rds = %5B' +pine apple', @@ -4067,30 +4067,37 @@ ', ' -pear +orange ', ' -banana +mango ', ' -plum +watermelon '%5D%0A @@ -4219,55 +4219,8 @@ nd%0A%0A -# Method names can have question marks in them%0A # Us @@ -4242,30 +4242,41 @@ and -b +B ooleans -%0Adef over_fi + values%0Adef greater_se ve +n ?%0A%09v @@ -4282,17 +4282,17 @@ value = -3 +7 %0A%09puts v @@ -4302,34 +4302,40 @@ e %3E -5 +7 ? ' -Over 5' : 'Not over 5 +More than 7' : 'Less than 7 '%0Aen @@ -4398,19 +4398,18 @@ re %60 -welcome,add +course,sub ,lon @@ -4422,25 +4422,29 @@ ord and -over_fi +greater_se ve +n %60%0ABehavi @@ -4454,14 +4454,13 @@ :%0A%0A%60 -welcom +cours e%60: @@ -4570,19 +4570,19 @@ ing %E2%80%9D%0A%0A%60 -add +sub %60:This m @@ -4669,17 +4669,17 @@ ich are -2 +7 and 3%0A%0A @@ -4926,17 +4926,21 @@ .%0A%0A%60 -over_fi +greater_se ve +n ?%60: @@ -5416,38 +5416,38 @@ mple:%0A%60%60%60%0Aclass -Animal +Person %0A def set_noise @@ -5525,36 +5525,42 @@ nd%0A%0A -animal1 = Animal.new%0Aanimal1 +person_one = Person.new%0Aperson_one .set @@ -5559,35 +5559,37 @@ _one.set_noise(%22 -Moo +Laugh !%22)%0Aputs animal1 @@ -5573,39 +5573,42 @@ (%22Laugh!%22)%0Aputs -animal1 +person_one .make_noise%0A%0Aani @@ -5608,36 +5608,42 @@ se%0A%0A -animal2 = Animal.new%0Aanimal2 +person_two = Person.new%0Aperson_two .set @@ -5642,37 +5642,37 @@ _two.set_noise(%22 -Quack +Groan !%22)%0Aputs animal2 @@ -5656,39 +5656,42 @@ (%22Groan!%22)%0Aputs -animal2 +person_two .make_noise%0A%0A%60%60%60 @@ -6199,18 +6199,16 @@ ethods%0A%0A -%0A%0A The firs @@ -6722,30 +6722,30 @@ :%0A%60%60%60%0Aclass -Animal +Person %0A def set_n @@ -6788,36 +6788,42 @@ %0A %0A -animal1 = Animal.new%0Aanimal1 +person_one = Person.new%0Aperson_one .set @@ -6822,35 +6822,37 @@ _one.set_noise(%22 -Moo +Laugh !%22)%0Aputs animal1 @@ -6836,39 +6836,42 @@ (%22Laugh!%22)%0Aputs -animal1 +person_one .make_noise%0A%0Aani @@ -6871,36 +6871,42 @@ se%0A%0A -animal2 = Animal.new%0Aanimal2 +person_two = Person.new%0Aperson_two .set @@ -6905,37 +6905,37 @@ _two.set_noise(%22 -Quack +Groan !%22)%0Aputs animal2 @@ -6919,39 +6919,42 @@ (%22Groan!%22)%0Aputs -animal2 +person_two .make_noise%0A%60%60%60%0A @@ -7139,22 +7139,22 @@ %60%0Aclass -Animal +Person %0A %0A de @@ -7192,36 +7192,42 @@ nd%0A%0A -animal1 = Animal.new%0Aanimal1 +person_one = Person.new%0Aperson_one .set @@ -7234,19 +7234,21 @@ _noise(%22 -Moo +Laugh !%22)%0Aputs @@ -7248,23 +7248,26 @@ %22)%0Aputs -animal1 +person_one .make_no @@ -7275,36 +7275,42 @@ se%0A%0A -animal2 = Animal.new%0Aanimal2 +person_two = Person.new%0Aperson_two .set @@ -7317,21 +7317,21 @@ _noise(%22 -Quack +Groan !%22)%0Aputs @@ -7331,23 +7331,26 @@ %22)%0Aputs -animal2 +person_two .make_no @@ -7796,22 +7796,22 @@ it asks -Animal +Person to do t @@ -7916,22 +7916,22 @@ %60%0Aclass -Animal +Person %0A def n @@ -8009,36 +8009,42 @@ nd%0A%0A -animal1 = Animal.new%0Aanimal1 +person_one = Person.new%0Aperson_one .noi @@ -8053,62 +8053,73 @@ = %22 -Moo +Laugh !%22%0Aputs -animal1.noise%0A%0Aanimal2 = Animal.new%0Aanimal2 +person_one.noise%0A%0Aperson_two = Person.new%0Aperson_two .noi @@ -8128,28 +8128,31 @@ = %22 -Quack +Groan !%22%0Aputs -animal2 +person_two .noi @@ -8170,15 +8170,18 @@ ow%60 -animal1 +person_one .noi @@ -8193,15 +8193,18 @@ nd %60 -animal2 +person_two .noi
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":538746,"name":"ruby","full_name":"ruby/ruby","html_url":"https://github.com/ruby/ruby","fork":false,"owner":{"login":"ruby"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","ruby","app","development","utopian-io"],"users":["noise"]}
Transaction InfoBlock #22058392/Trx 89c29b9840788f63318d928faf2b33adce42e4aa
View Raw JSON Data
{
  "trx_id": "89c29b9840788f63318d928faf2b33adce42e4aa",
  "block": 22058392,
  "trx_in_block": 26,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T20:40:15",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "title": "Advance Ruby Development Episode-1",
      "body": "@@ -1361,16 +1361,18 @@\n s Ruby?%0A\n+%0A%0A\n Ruby is \n@@ -1815,18 +1815,16 @@\n Ruby. %0A%0A\n-%0A%0A\n  With Ru\n@@ -2619,16 +2619,18 @@\n (IRB) ?%0A\n+%0A%0A\n Interact\n@@ -3866,22 +3866,21 @@\n %60%60%60%0Adef \n-welcom\n+cours\n e%0A%09puts \n@@ -3933,22 +3933,20 @@\n def \n-add\n+sub\n %0A%09puts \n-2 + \n+7-\n 3%0Aen\n@@ -3961,16 +3961,28 @@\n erscore \n+can be used \n between \n@@ -4007,16 +4007,29 @@\n le names\n+ in this case\n %0Adef lon\n@@ -4050,16 +4050,20 @@\n rds = %5B'\n+pine\n apple', \n@@ -4067,30 +4067,37 @@\n ', '\n-pear\n+orange\n ', '\n-banana\n+mango\n ', '\n-plum\n+watermelon\n '%5D%0A \n@@ -4219,55 +4219,8 @@\n nd%0A%0A\n-# Method names can have question marks in them%0A\n # Us\n@@ -4242,30 +4242,41 @@\n and \n-b\n+B\n ooleans\n-%0Adef over_fi\n+ values%0Adef greater_se\n ve\n+n\n ?%0A%09v\n@@ -4282,17 +4282,17 @@\n value = \n-3\n+7\n %0A%09puts v\n@@ -4302,34 +4302,40 @@\n e %3E \n-5\n+7\n  ? '\n-Over 5' : 'Not over 5\n+More than 7' : 'Less than 7\n '%0Aen\n@@ -4398,19 +4398,18 @@\n re %60\n-welcome,add\n+course,sub\n ,lon\n@@ -4422,25 +4422,29 @@\n ord and \n-over_fi\n+greater_se\n ve\n+n\n %60%0ABehavi\n@@ -4454,14 +4454,13 @@\n :%0A%0A%60\n-welcom\n+cours\n e%60: \n@@ -4570,19 +4570,19 @@\n ing %E2%80%9D%0A%0A%60\n-add\n+sub\n %60:This m\n@@ -4669,17 +4669,17 @@\n ich are \n-2\n+7\n  and 3%0A%0A\n@@ -4926,17 +4926,21 @@\n .%0A%0A%60\n-over_fi\n+greater_se\n ve\n+n\n ?%60: \n@@ -5416,38 +5416,38 @@\n mple:%0A%60%60%60%0Aclass \n-Animal\n+Person\n %0A  def set_noise\n@@ -5525,36 +5525,42 @@\n nd%0A%0A\n-animal1 = Animal.new%0Aanimal1\n+person_one = Person.new%0Aperson_one\n .set\n@@ -5559,35 +5559,37 @@\n _one.set_noise(%22\n-Moo\n+Laugh\n !%22)%0Aputs animal1\n@@ -5573,39 +5573,42 @@\n (%22Laugh!%22)%0Aputs \n-animal1\n+person_one\n .make_noise%0A%0Aani\n@@ -5608,36 +5608,42 @@\n se%0A%0A\n-animal2 = Animal.new%0Aanimal2\n+person_two = Person.new%0Aperson_two\n .set\n@@ -5642,37 +5642,37 @@\n _two.set_noise(%22\n-Quack\n+Groan\n !%22)%0Aputs animal2\n@@ -5656,39 +5656,42 @@\n (%22Groan!%22)%0Aputs \n-animal2\n+person_two\n .make_noise%0A%0A%60%60%60\n@@ -6199,18 +6199,16 @@\n ethods%0A%0A\n-%0A%0A\n The firs\n@@ -6722,30 +6722,30 @@\n :%0A%60%60%60%0Aclass \n-Animal\n+Person\n %0A  def set_n\n@@ -6788,36 +6788,42 @@\n %0A  %0A\n-animal1 = Animal.new%0Aanimal1\n+person_one = Person.new%0Aperson_one\n .set\n@@ -6822,35 +6822,37 @@\n _one.set_noise(%22\n-Moo\n+Laugh\n !%22)%0Aputs animal1\n@@ -6836,39 +6836,42 @@\n (%22Laugh!%22)%0Aputs \n-animal1\n+person_one\n .make_noise%0A%0Aani\n@@ -6871,36 +6871,42 @@\n se%0A%0A\n-animal2 = Animal.new%0Aanimal2\n+person_two = Person.new%0Aperson_two\n .set\n@@ -6905,37 +6905,37 @@\n _two.set_noise(%22\n-Quack\n+Groan\n !%22)%0Aputs animal2\n@@ -6919,39 +6919,42 @@\n (%22Groan!%22)%0Aputs \n-animal2\n+person_two\n .make_noise%0A%60%60%60%0A\n@@ -7139,22 +7139,22 @@\n %60%0Aclass \n-Animal\n+Person\n %0A  %0A  de\n@@ -7192,36 +7192,42 @@\n nd%0A%0A\n-animal1 = Animal.new%0Aanimal1\n+person_one = Person.new%0Aperson_one\n .set\n@@ -7234,19 +7234,21 @@\n _noise(%22\n-Moo\n+Laugh\n !%22)%0Aputs\n@@ -7248,23 +7248,26 @@\n %22)%0Aputs \n-animal1\n+person_one\n .make_no\n@@ -7275,36 +7275,42 @@\n se%0A%0A\n-animal2 = Animal.new%0Aanimal2\n+person_two = Person.new%0Aperson_two\n .set\n@@ -7317,21 +7317,21 @@\n _noise(%22\n-Quack\n+Groan\n !%22)%0Aputs\n@@ -7331,23 +7331,26 @@\n %22)%0Aputs \n-animal2\n+person_two\n .make_no\n@@ -7796,22 +7796,22 @@\n it asks \n-Animal\n+Person\n  to do t\n@@ -7916,22 +7916,22 @@\n %60%0Aclass \n-Animal\n+Person\n %0A  def n\n@@ -8009,36 +8009,42 @@\n nd%0A%0A\n-animal1 = Animal.new%0Aanimal1\n+person_one = Person.new%0Aperson_one\n .noi\n@@ -8053,62 +8053,73 @@\n  = %22\n-Moo\n+Laugh\n !%22%0Aputs \n-animal1.noise%0A%0Aanimal2 = Animal.new%0Aanimal2\n+person_one.noise%0A%0Aperson_two = Person.new%0Aperson_two\n .noi\n@@ -8128,28 +8128,31 @@\n  = %22\n-Quack\n+Groan\n !%22%0Aputs \n-animal2\n+person_two\n .noi\n@@ -8170,15 +8170,18 @@\n ow%60 \n-animal1\n+person_one\n .noi\n@@ -8193,15 +8193,18 @@\n nd %60\n-animal2\n+person_two\n .noi\n",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":538746,\"name\":\"ruby\",\"full_name\":\"ruby/ruby\",\"html_url\":\"https://github.com/ruby/ruby\",\"fork\":false,\"owner\":{\"login\":\"ruby\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"ruby\",\"app\",\"development\",\"utopian-io\"],\"users\":[\"noise\"]}"
    }
  ]
}
2018/05/01 17:48:36
parent author
parent permlinkutopian-io
authorexploringworld
permlinkadvance-ruby-development-episode-1
titleAdvance Ruby Development Episode-1
body@@ -4440,16 +4440,17 @@ aviour:%0A +%0A %60welcome @@ -4561,16 +4561,17 @@ mming %E2%80%9D%0A +%0A %60add%60:Th @@ -4670,16 +4670,17 @@ 2 and 3%0A +%0A %60longest @@ -4913,16 +4913,17 @@ h time.%0A +%0A %60over_fi @@ -5052,16 +5052,17 @@ its end%0A +%0A #### Rea @@ -6348,17 +6348,19 @@ ook like -, +.%0A%0A %60set_no
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":538746,"name":"ruby","full_name":"ruby/ruby","html_url":"https://github.com/ruby/ruby","fork":false,"owner":{"login":"ruby"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","ruby","app","development","utopian-io"],"users":["noise"]}
Transaction InfoBlock #22054959/Trx 73fd395dd54c008e159bbee8fe3947663ee18eac
View Raw JSON Data
{
  "trx_id": "73fd395dd54c008e159bbee8fe3947663ee18eac",
  "block": 22054959,
  "trx_in_block": 34,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T17:48:36",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "title": "Advance Ruby Development Episode-1",
      "body": "@@ -4440,16 +4440,17 @@\n aviour:%0A\n+%0A\n %60welcome\n@@ -4561,16 +4561,17 @@\n mming %E2%80%9D%0A\n+%0A\n %60add%60:Th\n@@ -4670,16 +4670,17 @@\n 2 and 3%0A\n+%0A\n %60longest\n@@ -4913,16 +4913,17 @@\n h time.%0A\n+%0A\n %60over_fi\n@@ -5052,16 +5052,17 @@\n its end%0A\n+%0A\n #### Rea\n@@ -6348,17 +6348,19 @@\n ook like\n-,\n+.%0A%0A\n  %60set_no\n",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":538746,\"name\":\"ruby\",\"full_name\":\"ruby/ruby\",\"html_url\":\"https://github.com/ruby/ruby\",\"fork\":false,\"owner\":{\"login\":\"ruby\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"ruby\",\"app\",\"development\",\"utopian-io\"],\"users\":[\"noise\"]}"
    }
  ]
}
2018/05/01 16:24:48
voternexusprime
authorexploringworld
permlinkadvance-ruby-development-episode-1
weight10000 (100.00%)
Transaction InfoBlock #22053284/Trx 98b8a130a2deff1174ea0699e2dbb4e5a1294702
View Raw JSON Data
{
  "trx_id": "98b8a130a2deff1174ea0699e2dbb4e5a1294702",
  "block": 22053284,
  "trx_in_block": 35,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T16:24:48",
  "op": [
    "vote",
    {
      "voter": "nexusprime",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "weight": 10000
    }
  ]
}
2018/05/01 13:55:03
parent author
parent permlinkutopian-io
authorexploringworld
permlinkadvance-ruby-development-episode-1
titleAdvance Ruby Development Episode-1
body@@ -1813,16 +1813,18 @@ Ruby. %0A%0A +%0A%0A With Ru @@ -2575,16 +2575,21 @@ y=7%0A%60%0A%0A +#### What is @@ -6163,16 +6163,18 @@ ethods%0A%0A +%0A%0A The firs
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":538746,"name":"ruby","full_name":"ruby/ruby","html_url":"https://github.com/ruby/ruby","fork":false,"owner":{"login":"ruby"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","ruby","app","development","utopian-io"],"users":["noise"]}
Transaction InfoBlock #22050290/Trx 94d8ec0d0c462fa0ac50564a44b2e7276114291f
View Raw JSON Data
{
  "trx_id": "94d8ec0d0c462fa0ac50564a44b2e7276114291f",
  "block": 22050290,
  "trx_in_block": 41,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T13:55:03",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "title": "Advance Ruby Development Episode-1",
      "body": "@@ -1813,16 +1813,18 @@\n Ruby. %0A%0A\n+%0A%0A\n  With Ru\n@@ -2575,16 +2575,21 @@\n  y=7%0A%60%0A%0A\n+#### \n What is \n@@ -6163,16 +6163,18 @@\n ethods%0A%0A\n+%0A%0A\n The firs\n",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":538746,\"name\":\"ruby\",\"full_name\":\"ruby/ruby\",\"html_url\":\"https://github.com/ruby/ruby\",\"fork\":false,\"owner\":{\"login\":\"ruby\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"ruby\",\"app\",\"development\",\"utopian-io\"],\"users\":[\"noise\"]}"
    }
  ]
}
2018/05/01 13:16:24
voterleir
authorexploringworld
permlinkadvance-ruby-development-episode-1
weight2000 (20.00%)
Transaction InfoBlock #22049517/Trx 6696a5204a652203024a8d34d2b4bc051b4cdf95
View Raw JSON Data
{
  "trx_id": "6696a5204a652203024a8d34d2b4bc051b4cdf95",
  "block": 22049517,
  "trx_in_block": 15,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T13:16:24",
  "op": [
    "vote",
    {
      "voter": "leir",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "weight": 2000
    }
  ]
}
2018/05/01 13:11:18
parent authorexploringworld
parent permlinkadvance-ruby-development-episode-1
authorsteemboy9
permlinkre-advance-ruby-development-episode-1-20180501t131116
title
bodyAmazing post! I love it. Hey UPVOTE my post: https://steemit.com/life/@cryptopaparazzi/chapter-one-let-there-be-the-man-and-there-was-a-man-let-there-be-a-woman-and-there-was-sex and FOLLOW ME and I ll do the same :)
json metadata
Transaction InfoBlock #22049415/Trx 1ceb5a175f0d62852d1d486c01e0b38cef701bdd
View Raw JSON Data
{
  "trx_id": "1ceb5a175f0d62852d1d486c01e0b38cef701bdd",
  "block": 22049415,
  "trx_in_block": 1,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T13:11:18",
  "op": [
    "comment",
    {
      "parent_author": "exploringworld",
      "parent_permlink": "advance-ruby-development-episode-1",
      "author": "steemboy9",
      "permlink": "re-advance-ruby-development-episode-1-20180501t131116",
      "title": "",
      "body": "Amazing post! I love it. Hey UPVOTE my post: https://steemit.com/life/@cryptopaparazzi/chapter-one-let-there-be-the-man-and-there-was-a-man-let-there-be-a-woman-and-there-was-sex and FOLLOW ME and I ll do the same :)",
      "json_metadata": ""
    }
  ]
}
2018/05/01 13:07:03
voteraafeng
authorexploringworld
permlinkadvance-ruby-development-episode-1
weight1500 (15.00%)
Transaction InfoBlock #22049331/Trx 2845bc6998929ecc66323dd8b934a991102c381f
View Raw JSON Data
{
  "trx_id": "2845bc6998929ecc66323dd8b934a991102c381f",
  "block": 22049331,
  "trx_in_block": 20,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T13:07:03",
  "op": [
    "vote",
    {
      "voter": "aafeng",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "weight": 1500
    }
  ]
}
2018/05/01 12:56:42
voterjosephace135
authorexploringworld
permlinkadvance-ruby-development-episode-1
weight3000 (30.00%)
Transaction InfoBlock #22049124/Trx 4802a6610f4bf1175551d1400f1db6cc53b33752
View Raw JSON Data
{
  "trx_id": "4802a6610f4bf1175551d1400f1db6cc53b33752",
  "block": 22049124,
  "trx_in_block": 13,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T12:56:42",
  "op": [
    "vote",
    {
      "voter": "josephace135",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "weight": 3000
    }
  ]
}
2018/05/01 12:56:12
parent author
parent permlinkutopian-io
authorexploringworld
permlinkadvance-ruby-development-episode-1
titleAdvance Ruby Development Episode-1
body#### Welcome to the First Tutorial of Advance Ruby Development <center> <img src= https://imgur.com/MILXLd2.jpg/> </center> #### What Will I Learn? - You will learn how to develop Applications using Ruby - You will learn about IRB shell in Ruby programming - You will learn about various class methods and their usage - Your will learn about reading and writing through class methods #### Requirements ##### System Requirements: - [Ruby Installer]( https://www.ruby-lang.org/en/downloads/) for building apps - [SciTE]( https://www.scintilla.org/ScintillaDownload.html) for code editing - Command Prompt or Terminal ##### OS Support: - Windows 7/8/10 - macOS - Linux #### Difficulty - Intermediate #### Required Understanding - You just need a little bit of knowledge basic Ruby Syntax - A fair understanding of Programming - A thirst for learning and developing something new #### Description - In this Advance Ruby Development course, I will teach you the advanced concepts of the Ruby programming language. Ruby was designed to be more powerful that Perl, and more object-oriented than Python, and has gained in popularity due to its power and ease of use. By the end of this course you will surely develop some powerful and concrete applications. Also in the end of this course we will be developing a Restaurant finder app. #### What is Ruby? Ruby is an object-oriented, general purpose programming language designed by Yukihiro Matsumoto in the 1990s. Intended for improved productivity and entertaining, it creates a great starter language for first time programmers because of its simplicity, readability and concentrate on fun. Commonly used with Rails applications, that is a very popular language that is always in popularity. Organizations such as Twitter and Kickstarter utilize Ruby. With Ruby, almost everything is an object. Every bit of information as well as codes can be provided their very own attributes and actions. Object-oriented programming calls attributes by the title instance variables and also actions tend to be known as methods. Ruby’s genuine object-oriented approach is quite commonly demonstrated with a bit of code that is applicable an action to a number. ``` 7.times { print "I *like* Open Source Projects" } ``` As an example, addition is conducted with the `plus (+)` operator. However, if you would instead use the readable word `plus`, you can add this type of method to Ruby’s builtin Numeric class. ``` class Numeric def plus(x) self.+(x) end end y = 4.plus 3 ``` `which results in the value of y=7 ` What is Interactive Ruby Shell (IRB) ? Interactive Ruby Shell (IRB ) is actually a REPL with regard to coding in the Ruby Language. Typically the abbreviation irb originates from the point that the filename extension for Ruby is **.rb**, even though interactive Ruby files don’t have an extension involving **.irb**. The program will be launched from the command line and enables the execution of Ruby commands with immediate response, testing in real-time. This features command record, line modifying capabilities, and job control, and it is capable of communicate directly being a shell script on the internet and also connect to a live server. `irb [ options ] [ programfile ] [ argument... ] ` ##### Example: ``` irb(main):001:0> num = 4 => 4 irb(main):002:0> def fact(num) irb(main):003:1> if num <= 1 irb(main):004:2> 1 irb(main):005:2> else irb(main):006:2* num * fact(num - 1) irb(main):007:2> end irb(main):008:1> end => :fact irb(main):009:0> fact(num) => 24 ``` Methods In Ruby Programming Ruby uses methods to use a block of codes. In other programming languages some other techniques are used like functions and procedures. Now we will have al look at methods in ruby and then we proceed to the next level. **Let have a look at this example** ``` def welcome puts "This course is about Ruby Programming " end def add puts 2 + 3 end # Underscore between words, like variable names def longest_word words = ['apple', 'pear', 'banana', 'plum'] longest_word = words.inject do |memo,word| memo.length > word.length ? memo : word end puts longest_word end # Method names can have question marks in them # Useful for tests and booleans def over_five? value = 3 puts value > 5 ? 'Over 5' : 'Not over 5' end ``` In the above example I define four methods which are `welcome,add,longest_word and over_five` Behaviour: `welcome`: It simply displays a message on the screen which is in this case is “This course is about Ruby Programming ” `add`:This method simply perform the addition of two number which is passed as arguments which are 2 and 3 `longest_word`: This method does a little interesting job here,it returns me the longest word out of an array of four words by using the `inject` function which accumulates and returns the longest length word by increment the memo each time. `over_five?`: This methods basically testing which number is greater between the two and returns the Boolean value. It uses `?`at its end #### Reading and Writing Operations: Ruby has methods for Reading and Writing known as Reader and Writer. Other languages have getters and setter for this reading/writing in programs. These methods will allow us to read data from a program or write data to it. Later these operations will help us in making our restaurant finder app. #### Example: ``` class Animal def set_noise(noise) @noise = noise end def make_noise @noise end end animal1 = Animal.new animal1.set_noise("Moo!") puts animal1.make_noise animal2 = Animal.new animal2.set_noise("Quack!") puts animal2.make_noise ``` Now this is a very common feature of object-oriented programming languages, sometimes in other languages, they're called getter and setter methods. Either one is fine. You can use either name, typically in Ruby, we're going to call them reader and writer methods. So, here is the code which is a perfect example to explain, what we're looking for is a pairing of something that will set a value for us and something that will get a value for us, and that's exactly what we already have with our two methods The first one is a setter method or a writer method. So we're setting the value of noise equal to a value, and this is the classic format for what a setter method would look like, `set_noise` equal to a value. It sets it for us. Then we have a `get_noise`. It's a getter method. The idea is that we are getting that value back. One of these methods sets it, one of them gets it. Now the important thing about these two methods is that they give us access control over these instance variables. So for **example**: ``` class Animal def set_noise(noise) @noise = noise end animal1 = Animal.new animal1.set_noise("Moo!") puts animal1.make_noise animal2 = Animal.new animal2.set_noise("Quack!") puts animal2.make_noise ``` if we were to take away `get_noise`, now we have no way to get that value back. Of course, we could write another method that would do it for us, but our getter method is gone ``` class Animal def make_noise @noise end end animal1 = Animal.new animal1.set_noise("Moo!") puts animal1.make_noise animal2 = Animal.new animal2.set_noise("Quack!") puts animal2.make_noise ``` Same thing here, if we were to take away `set_noise`, now we have no way to set it by calling a method. we need a setter method if we want to be able to do it directly. Like `set_noise` and `get_noise` and using underscore writing approach is very common in a lot of programming languages. In Ruby though, we can make use of that syntactic sugar that we looked at earlier, and so we can take get _out and simply ask for noise. So it asks Animal to do the method noise, which returns the instance variable, noise. It's a very commonsense approach. ``` class Animal def noise=(noise) @noise = noise end def noise @noise end end animal1 = Animal.new animal1.noise = "Moo!" puts animal1.noise animal2 = Animal.new animal2.noise = "Quack!" puts animal2.noise ``` So now` animal1.noise` and `animal2.noise` just returns that to us, where the syntactic sugar comes in is that we can do the same thing with set, we can take away set and just say `noise=(noise).` #### Summary In this tutorial of Advance Ruby Development we learn about the methods, also now we have a better understanding of reading and writing using methods in Ruby. In the next tutorial we will learn about modules and development of our Restaurant Finder App.
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":538746,"name":"ruby","full_name":"ruby/ruby","html_url":"https://github.com/ruby/ruby","fork":false,"owner":{"login":"ruby"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","utopian-io","ruby","app","development"],"users":["noise"],"moderator":{"account":"portugalcoin","time":"2018-05-01T12:56:13.464Z","pending":true,"reviewed":false,"flagged":false},"config":{"questions":[{"question":"How many substantial concepts does this tutorial address?","question_id":"tuts-1","answers":[{"answer":"4-5 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-1","value":10},{"answer":"2-3 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-2","value":7},{"answer":"1 substantial concept covered in the tutorial.","answer_id":"tuts-1-a-3","value":3},{"answer":"More than 5 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-4","value":0}]},{"question":"Does the title and the outline of the tutorial properly reflect the content?","question_id":"tuts-2","answers":[{"answer":"Yes, it is very clear.","answer_id":"tuts-2-a-1","value":15},{"answer":"To some extent.","answer_id":"tuts-2-a-2","value":11.5},{"answer":"The title is somewhat misleading and/or the outline is not detailed or informative enough.","answer_id":"tuts-2-a-3","value":4.5},{"answer":"Title and outline are of little or no relevance to the content of the tutorial.","answer_id":"tuts-2-a-4","value":0}]},{"question":"Did the contributor provide supplementary resources, such as code and sample files in the contribution post or a linked GitHub repository?","question_id":"tuts-3","answers":[{"answer":"Yes, exceptional supplementary resources are provided including a relevant github repo/gist.","answer_id":"tuts-3-a-1","value":15},{"answer":"Supplementary resources provided are of high relevance.","answer_id":"tuts-3-a-2","value":12},{"answer":"Contributor provides minimal supplementary resources.","answer_id":"tuts-3-a-3","value":6},{"answer":"No supplementary resources were provided.","answer_id":"tuts-3-a-4","value":0}]},{"question":"Is the tutorial part of a series?","question_id":"tuts-4","answers":[{"answer":"Yes.","answer_id":"tuts-4-a-1","value":10},{"answer":"Yes, but it is the first entry in the series.","answer_id":"tuts-4-a-2","value":7},{"answer":"No, but it works just fine as a stand-alone tutorial.","answer_id":"tuts-4-a-3","value":5},{"answer":"No.","answer_id":"tuts-4-a-4","value":0}]},{"question":"Does the tutorial contain sufficient explanatory visuals?","question_id":"tuts-5","answers":[{"answer":"Yes, the visual components of the post were adequate in quality and quantity.","answer_id":"tuts-5-a-1","value":10},{"answer":"The volume of visual components included was unnecessarily large.","answer_id":"tuts-5-a-2","value":7},{"answer":"The post lacked sufficient visualization to easily learn from the content.","answer_id":"tuts-5-a-3","value":3},{"answer":"No visualization was presented in this contribution.","answer_id":"tuts-5-a-4","value":0}]},{"question":"How unique and/or innovative are the concepts covered in the tutorial?","question_id":"tuts-6","answers":[{"answer":"This was the first time I read about the concepts covered.","answer_id":"tuts-6-a-1","value":10},{"answer":"The concepts covered were innovative and offer some usefulness.","answer_id":"tuts-6-a-2","value":7},{"answer":"I have read several similar ideas and thoughts elsewhere, but this one was of higher quality.","answer_id":"tuts-6-a-3","value":5},{"answer":"Such tutorials can be found online with great ease and the contribution add no value to the open source community.","answer_id":"tuts-6-a-4","value":0}]},{"question":"How would you describe the formatting, language and overall presentation of the post?","question_id":"c-1","answers":[{"answer":"The post is of very high quality.","answer_id":"c-1-a-1","value":10},{"answer":"The post is of decent quality, but not spectacular in any way.","answer_id":"c-1-a-2","value":7},{"answer":"The post is poorly written and/or formatted, but readable.","answer_id":"c-1-a-3","value":3},{"answer":"The post is really hard to read and the content is barely understandable.","answer_id":"c-1-a-4","value":0}]},{"question":"How would you rate the overall value of this contribution on the open source community and ecosystem?","question_id":"c-2","answers":[{"answer":"This contribution brings great and impactful value, and can be used for applications outside the specific project.","answer_id":"c-2-a-1","value":20},{"answer":"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.","answer_id":"c-2-a-2","value":16},{"answer":"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.","answer_id":"c-2-a-3","value":8},{"answer":"This contribution adds no value to the open source community and ecosystem or the specific project.","answer_id":"c-2-a-4","value":0}]}]}}
Transaction InfoBlock #22049114/Trx 5b3596cd9447e11b21111cd4bcf39f2b07c7742a
View Raw JSON Data
{
  "trx_id": "5b3596cd9447e11b21111cd4bcf39f2b07c7742a",
  "block": 22049114,
  "trx_in_block": 43,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T12:56:12",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "title": "Advance Ruby Development Episode-1",
      "body": "#### Welcome to the First Tutorial of Advance Ruby Development\n<center> <img src= https://imgur.com/MILXLd2.jpg/> </center>\n\n#### What Will I Learn?\n\n- You will learn how to develop Applications using Ruby \n- You will learn about IRB shell in Ruby programming \n- You will learn about various class methods and their usage\n- Your will learn about reading and writing through class methods\n\n\n\n#### Requirements\n##### System Requirements:\n\n- [Ruby Installer]( https://www.ruby-lang.org/en/downloads/) for building apps\n- [SciTE]( https://www.scintilla.org/ScintillaDownload.html) for code editing \n- Command Prompt or Terminal \n##### OS Support:\n\n- Windows 7/8/10\n- macOS \n- Linux \n#### Difficulty\n\n\n\n- Intermediate\n\n#### Required Understanding\n- You just need a little bit of knowledge basic Ruby Syntax\n- A fair understanding of Programming \n- A thirst for learning and developing something new\n\n\n#### Description\n-\tIn this Advance Ruby Development course, I will teach you the advanced concepts of the Ruby programming language. Ruby was designed to be more powerful that Perl, and more object-oriented than Python, and has gained in popularity due to its power and ease of use. By the end of this course you will surely develop some powerful and concrete applications. Also in the end of this course we will be developing a Restaurant finder app.\n\n#### What is Ruby?\nRuby is an object-oriented, general purpose programming language designed by Yukihiro Matsumoto in the 1990s. Intended for improved productivity and entertaining, it creates a great starter language for first time programmers because of its simplicity, readability and concentrate on fun. Commonly used with Rails applications, that is a very popular language that is always in popularity. Organizations such as Twitter and Kickstarter utilize Ruby. \n\n With Ruby, almost everything is an object. Every bit of information as well as codes can be provided their very own attributes and actions. Object-oriented programming calls attributes by the title instance variables and also actions tend to be known as methods. Ruby’s genuine object-oriented approach is quite commonly demonstrated with a bit of code that is applicable an action to a number.\n```\n7.times { print \"I *like* Open Source Projects\" }\n\n```\nAs an example, addition is conducted with the `plus (+)` operator. However, if you would instead use the readable word `plus`, you can add this type of method to Ruby’s builtin Numeric class.\n```\nclass Numeric\n  def plus(x)\n    self.+(x)\n  end\nend\n\ny = 4.plus 3\n\n```\n`which results in the value of y=7\n`\n\nWhat is Interactive Ruby Shell (IRB) ?\nInteractive Ruby Shell (IRB ) is actually a REPL with regard to coding in the Ruby Language. Typically the abbreviation irb originates from the point that the filename extension for Ruby is **.rb**, even though interactive Ruby files don’t have an extension involving **.irb**.\n\nThe program will be launched from the command line and enables the execution of Ruby commands with immediate response, testing in real-time. This features command record, line modifying capabilities, and job control, and it is capable of communicate directly being a shell script on the internet and also connect to a live server.\n`irb [ options ] [ programfile ] [ argument... ] `\n##### Example:\n```\nirb(main):001:0> num = 4\n=> 4\nirb(main):002:0> def fact(num)\nirb(main):003:1>   if num <= 1\nirb(main):004:2>     1\nirb(main):005:2>   else\nirb(main):006:2*     num * fact(num - 1)\nirb(main):007:2>   end\nirb(main):008:1> end\n=> :fact\nirb(main):009:0> fact(num)\n=> 24\n```\n\n\nMethods In Ruby Programming\nRuby uses methods to use a block of codes. In other programming languages some other techniques are used like functions and procedures. Now we will have al look at methods in ruby and then we proceed to the next level.\n\n**Let have a look at this example**\n\n```\ndef welcome\n\tputs \"This course is about Ruby Programming \"\nend\n\ndef add\n\tputs 2 + 3\nend\n\n# Underscore between words, like variable names\ndef longest_word\n  words = ['apple', 'pear', 'banana', 'plum']\n  longest_word = words.inject do |memo,word|\n    memo.length > word.length ? memo : word\n  end\n  puts longest_word\nend\n\n# Method names can have question marks in them\n# Useful for tests and booleans\ndef over_five?\n\tvalue = 3\n\tputs value > 5 ? 'Over 5' : 'Not over 5'\nend\n```\nIn the above example I define four methods which are `welcome,add,longest_word and over_five`\nBehaviour:\n`welcome`: It simply displays a message on the screen which is in this case is “This course is about Ruby Programming ”\n`add`:This method simply perform the addition of two number which is passed as arguments  which are 2 and 3\n`longest_word`: This method does a little interesting job here,it returns me the longest word out of an array of four words by using the `inject` function which accumulates and returns the longest length word by increment the memo each time.\n`over_five?`: This methods basically testing which number is greater between the two and returns the Boolean value. It uses `?`at its end\n#### Reading and Writing Operations:\n\nRuby has methods for Reading and Writing known as Reader and Writer. Other languages have getters and setter for this reading/writing in programs. These methods will allow us to read data from a program or write data to it. Later these operations will help us in making our restaurant finder app. \n#### Example:\n```\nclass Animal\n  def set_noise(noise)\n    @noise = noise\n  end\n  \n  def make_noise\n    @noise\n  end\nend\n\nanimal1 = Animal.new\nanimal1.set_noise(\"Moo!\")\nputs animal1.make_noise\n\nanimal2 = Animal.new\nanimal2.set_noise(\"Quack!\")\nputs animal2.make_noise\n\n```\nNow this is a very common feature of object-oriented programming languages, sometimes in other languages, they're called getter and setter methods. Either one is fine. You can use either name, typically in Ruby, we're going to call them reader and writer methods. So, here is the code which is a perfect example to explain, what we're looking for is a pairing of something that will set a value for us and something that will get a value for us, and that's exactly what we already have with our two methods\n\nThe first one is a setter method or a writer method. So we're setting the value of noise equal to a value, and this is the classic format for what a setter method would look like, `set_noise` equal to a value. It sets it for us. Then we have a  `get_noise`. It's a getter method. The idea is that we are getting that value back. One of these methods sets it, one of them gets it.\nNow the important thing about these two methods is that they give us access control over these instance variables. So for **example**:\n```\nclass Animal\n  def set_noise(noise)\n    @noise = noise\n  end\n  \nanimal1 = Animal.new\nanimal1.set_noise(\"Moo!\")\nputs animal1.make_noise\n\nanimal2 = Animal.new\nanimal2.set_noise(\"Quack!\")\nputs animal2.make_noise\n```\nif we were to take away `get_noise`, now we have no way to get that value back. Of course, we could write another method that would do it for us, but our getter method is gone\n```\nclass Animal\n  \n  def make_noise\n    @noise\n  end\nend\n\nanimal1 = Animal.new\nanimal1.set_noise(\"Moo!\")\nputs animal1.make_noise\n\nanimal2 = Animal.new\nanimal2.set_noise(\"Quack!\")\nputs animal2.make_noise\n```\nSame thing here, if we were to take away `set_noise`, now we have no way to set it by calling a method. we need a setter method if we want to be able to do it directly.\n\nLike `set_noise` and `get_noise` and using underscore writing approach is very common in a lot of programming languages. In Ruby though, we can make use of that syntactic sugar that we looked at earlier, and so we can take get _out and simply ask for noise. So it asks Animal to do the method noise, which returns the instance variable, noise. It's a very commonsense approach. \n```\nclass Animal\n  def noise=(noise)\n    @noise = noise\n  end\n  \n  def noise\n    @noise\n  end\nend\n\nanimal1 = Animal.new\nanimal1.noise = \"Moo!\"\nputs animal1.noise\n\nanimal2 = Animal.new\nanimal2.noise = \"Quack!\"\nputs animal2.noise\n```\nSo now` animal1.noise` and `animal2.noise` just returns that to us, where the syntactic sugar comes in is that we can do the same thing with set, we can take away set and just say `noise=(noise).`\n#### Summary\nIn this tutorial of Advance Ruby Development we learn about the methods, also now we have a better understanding of reading and writing using methods in Ruby. In the next tutorial we will learn about modules and development of our Restaurant Finder App.\n",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":538746,\"name\":\"ruby\",\"full_name\":\"ruby/ruby\",\"html_url\":\"https://github.com/ruby/ruby\",\"fork\":false,\"owner\":{\"login\":\"ruby\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"utopian-io\",\"ruby\",\"app\",\"development\"],\"users\":[\"noise\"],\"moderator\":{\"account\":\"portugalcoin\",\"time\":\"2018-05-01T12:56:13.464Z\",\"pending\":true,\"reviewed\":false,\"flagged\":false},\"config\":{\"questions\":[{\"question\":\"How many substantial concepts does this tutorial address?\",\"question_id\":\"tuts-1\",\"answers\":[{\"answer\":\"4-5 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-1\",\"value\":10},{\"answer\":\"2-3 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-2\",\"value\":7},{\"answer\":\"1 substantial concept covered in the tutorial.\",\"answer_id\":\"tuts-1-a-3\",\"value\":3},{\"answer\":\"More than 5 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-4\",\"value\":0}]},{\"question\":\"Does the title and the outline of the tutorial properly reflect the content?\",\"question_id\":\"tuts-2\",\"answers\":[{\"answer\":\"Yes, it is very clear.\",\"answer_id\":\"tuts-2-a-1\",\"value\":15},{\"answer\":\"To some extent.\",\"answer_id\":\"tuts-2-a-2\",\"value\":11.5},{\"answer\":\"The title is somewhat misleading and/or the outline is not detailed or informative enough.\",\"answer_id\":\"tuts-2-a-3\",\"value\":4.5},{\"answer\":\"Title and outline are of little or no relevance to the content of the tutorial.\",\"answer_id\":\"tuts-2-a-4\",\"value\":0}]},{\"question\":\"Did the contributor provide supplementary resources, such as code and sample files in the contribution post or a linked GitHub repository?\",\"question_id\":\"tuts-3\",\"answers\":[{\"answer\":\"Yes, exceptional supplementary resources are provided including a relevant github repo/gist.\",\"answer_id\":\"tuts-3-a-1\",\"value\":15},{\"answer\":\"Supplementary resources provided are of high relevance.\",\"answer_id\":\"tuts-3-a-2\",\"value\":12},{\"answer\":\"Contributor provides minimal supplementary resources.\",\"answer_id\":\"tuts-3-a-3\",\"value\":6},{\"answer\":\"No supplementary resources were provided.\",\"answer_id\":\"tuts-3-a-4\",\"value\":0}]},{\"question\":\"Is the tutorial part of a series?\",\"question_id\":\"tuts-4\",\"answers\":[{\"answer\":\"Yes.\",\"answer_id\":\"tuts-4-a-1\",\"value\":10},{\"answer\":\"Yes, but it is the first entry in the series.\",\"answer_id\":\"tuts-4-a-2\",\"value\":7},{\"answer\":\"No, but it works just fine as a stand-alone tutorial.\",\"answer_id\":\"tuts-4-a-3\",\"value\":5},{\"answer\":\"No.\",\"answer_id\":\"tuts-4-a-4\",\"value\":0}]},{\"question\":\"Does the tutorial contain sufficient explanatory visuals?\",\"question_id\":\"tuts-5\",\"answers\":[{\"answer\":\"Yes, the visual components of the post were adequate in quality and quantity.\",\"answer_id\":\"tuts-5-a-1\",\"value\":10},{\"answer\":\"The volume of visual components included was unnecessarily large.\",\"answer_id\":\"tuts-5-a-2\",\"value\":7},{\"answer\":\"The post lacked sufficient visualization to easily learn from the content.\",\"answer_id\":\"tuts-5-a-3\",\"value\":3},{\"answer\":\"No visualization was presented in this contribution.\",\"answer_id\":\"tuts-5-a-4\",\"value\":0}]},{\"question\":\"How unique and/or innovative are the concepts covered in the tutorial?\",\"question_id\":\"tuts-6\",\"answers\":[{\"answer\":\"This was the first time I read about the concepts covered.\",\"answer_id\":\"tuts-6-a-1\",\"value\":10},{\"answer\":\"The concepts covered were innovative and offer some usefulness.\",\"answer_id\":\"tuts-6-a-2\",\"value\":7},{\"answer\":\"I have read several similar ideas and thoughts elsewhere, but this one was of higher quality.\",\"answer_id\":\"tuts-6-a-3\",\"value\":5},{\"answer\":\"Such tutorials can be found online with great ease and the contribution add no value to the open source community.\",\"answer_id\":\"tuts-6-a-4\",\"value\":0}]},{\"question\":\"How would you describe the formatting, language and overall presentation of the post?\",\"question_id\":\"c-1\",\"answers\":[{\"answer\":\"The post is of very high quality.\",\"answer_id\":\"c-1-a-1\",\"value\":10},{\"answer\":\"The post is of decent quality, but not spectacular in any way.\",\"answer_id\":\"c-1-a-2\",\"value\":7},{\"answer\":\"The post is poorly written and/or formatted, but readable.\",\"answer_id\":\"c-1-a-3\",\"value\":3},{\"answer\":\"The post is really hard to read and the content is barely understandable.\",\"answer_id\":\"c-1-a-4\",\"value\":0}]},{\"question\":\"How would you rate the overall value of this contribution on the open source community and ecosystem?\",\"question_id\":\"c-2\",\"answers\":[{\"answer\":\"This contribution brings great and impactful value, and can be used for applications outside the specific project.\",\"answer_id\":\"c-2-a-1\",\"value\":20},{\"answer\":\"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.\",\"answer_id\":\"c-2-a-2\",\"value\":16},{\"answer\":\"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.\",\"answer_id\":\"c-2-a-3\",\"value\":8},{\"answer\":\"This contribution adds no value to the open source community and ecosystem or the specific project.\",\"answer_id\":\"c-2-a-4\",\"value\":0}]}]}}"
    }
  ]
}
2018/05/01 12:36:39
authorexploringworld
permlinkadvance-ruby-development-episode-1
max accepted payout1000000.000 SBD
percent steem dollars10000
allow votestrue
allow curation rewardstrue
extensions[[0,{"beneficiaries":[{"account":"utopian.pay","weight":1500}]}]]
Transaction InfoBlock #22048724/Trx afa35db883d9cc6efb12329e91f60cdb7111681f
View Raw JSON Data
{
  "trx_id": "afa35db883d9cc6efb12329e91f60cdb7111681f",
  "block": 22048724,
  "trx_in_block": 40,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T12:36:39",
  "op": [
    "comment_options",
    {
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "max_accepted_payout": "1000000.000 SBD",
      "percent_steem_dollars": 10000,
      "allow_votes": true,
      "allow_curation_rewards": true,
      "extensions": [
        [
          0,
          {
            "beneficiaries": [
              {
                "account": "utopian.pay",
                "weight": 1500
              }
            ]
          }
        ]
      ]
    }
  ]
}
2018/05/01 12:36:39
parent author
parent permlinkutopian-io
authorexploringworld
permlinkadvance-ruby-development-episode-1
titleAdvance Ruby Development Episode-1
body#### Welcome to the First Tutorial of Advance Ruby Development <center> <img src= https://imgur.com/MILXLd2.jpg/> </center> #### What Will I Learn? - You will learn how to develop Applications using Ruby - You will learn about IRB shell in Ruby programming - You will learn about various class methods and their usage - Your will learn about reading and writing through class methods #### Requirements ##### System Requirements: - [Ruby Installer]( https://www.ruby-lang.org/en/downloads/) for building apps - [SciTE]( https://www.scintilla.org/ScintillaDownload.html) for code editing - Command Prompt or Terminal ##### OS Support: - Windows 7/8/10 - macOS - Linux #### Difficulty - Intermediate #### Required Understanding - You just need a little bit of knowledge basic Ruby Syntax - A fair understanding of Programming - A thirst for learning and developing something new #### Description - In this Advance Ruby Development course, I will teach you the advanced concepts of the Ruby programming language. Ruby was designed to be more powerful that Perl, and more object-oriented than Python, and has gained in popularity due to its power and ease of use. By the end of this course you will surely develop some powerful and concrete applications. Also in the end of this course we will be developing a Restaurant finder app. #### What is Ruby? Ruby is an object-oriented, general purpose programming language designed by Yukihiro Matsumoto in the 1990s. Intended for improved productivity and entertaining, it creates a great starter language for first time programmers because of its simplicity, readability and concentrate on fun. Commonly used with Rails applications, that is a very popular language that is always in popularity. Organizations such as Twitter and Kickstarter utilize Ruby. With Ruby, almost everything is an object. Every bit of information as well as codes can be provided their very own attributes and actions. Object-oriented programming calls attributes by the title instance variables and also actions tend to be known as methods. Ruby’s genuine object-oriented approach is quite commonly demonstrated with a bit of code that is applicable an action to a number. ``` 7.times { print "I *like* Open Source Projects" } ``` As an example, addition is conducted with the `plus (+)` operator. However, if you would instead use the readable word `plus`, you can add this type of method to Ruby’s builtin Numeric class. ``` class Numeric def plus(x) self.+(x) end end y = 4.plus 3 ``` `which results in the value of y=7 ` What is Interactive Ruby Shell (IRB) ? Interactive Ruby Shell (IRB ) is actually a REPL with regard to coding in the Ruby Language. Typically the abbreviation irb originates from the point that the filename extension for Ruby is **.rb**, even though interactive Ruby files don’t have an extension involving **.irb**. The program will be launched from the command line and enables the execution of Ruby commands with immediate response, testing in real-time. This features command record, line modifying capabilities, and job control, and it is capable of communicate directly being a shell script on the internet and also connect to a live server. `irb [ options ] [ programfile ] [ argument... ] ` ##### Example: ``` irb(main):001:0> num = 4 => 4 irb(main):002:0> def fact(num) irb(main):003:1> if num <= 1 irb(main):004:2> 1 irb(main):005:2> else irb(main):006:2* num * fact(num - 1) irb(main):007:2> end irb(main):008:1> end => :fact irb(main):009:0> fact(num) => 24 ``` Methods In Ruby Programming Ruby uses methods to use a block of codes. In other programming languages some other techniques are used like functions and procedures. Now we will have al look at methods in ruby and then we proceed to the next level. **Let have a look at this example** ``` def welcome puts "This course is about Ruby Programming " end def add puts 2 + 3 end # Underscore between words, like variable names def longest_word words = ['apple', 'pear', 'banana', 'plum'] longest_word = words.inject do |memo,word| memo.length > word.length ? memo : word end puts longest_word end # Method names can have question marks in them # Useful for tests and booleans def over_five? value = 3 puts value > 5 ? 'Over 5' : 'Not over 5' end ``` In the above example I define four methods which are `welcome,add,longest_word and over_five` Behaviour: `welcome`: It simply displays a message on the screen which is in this case is “This course is about Ruby Programming ” `add`:This method simply perform the addition of two number which is passed as arguments which are 2 and 3 `longest_word`: This method does a little interesting job here,it returns me the longest word out of an array of four words by using the `inject` function which accumulates and returns the longest length word by increment the memo each time. `over_five?`: This methods basically testing which number is greater between the two and returns the Boolean value. It uses `?`at its end #### Reading and Writing Operations: Ruby has methods for Reading and Writing known as Reader and Writer. Other languages have getters and setter for this reading/writing in programs. These methods will allow us to read data from a program or write data to it. Later these operations will help us in making our restaurant finder app. #### Example: ``` class Animal def set_noise(noise) @noise = noise end def make_noise @noise end end animal1 = Animal.new animal1.set_noise("Moo!") puts animal1.make_noise animal2 = Animal.new animal2.set_noise("Quack!") puts animal2.make_noise ``` Now this is a very common feature of object-oriented programming languages, sometimes in other languages, they're called getter and setter methods. Either one is fine. You can use either name, typically in Ruby, we're going to call them reader and writer methods. So, here is the code which is a perfect example to explain, what we're looking for is a pairing of something that will set a value for us and something that will get a value for us, and that's exactly what we already have with our two methods The first one is a setter method or a writer method. So we're setting the value of noise equal to a value, and this is the classic format for what a setter method would look like, `set_noise` equal to a value. It sets it for us. Then we have a `get_noise`. It's a getter method. The idea is that we are getting that value back. One of these methods sets it, one of them gets it. Now the important thing about these two methods is that they give us access control over these instance variables. So for **example**: ``` class Animal def set_noise(noise) @noise = noise end animal1 = Animal.new animal1.set_noise("Moo!") puts animal1.make_noise animal2 = Animal.new animal2.set_noise("Quack!") puts animal2.make_noise ``` if we were to take away `get_noise`, now we have no way to get that value back. Of course, we could write another method that would do it for us, but our getter method is gone ``` class Animal def make_noise @noise end end animal1 = Animal.new animal1.set_noise("Moo!") puts animal1.make_noise animal2 = Animal.new animal2.set_noise("Quack!") puts animal2.make_noise ``` Same thing here, if we were to take away `set_noise`, now we have no way to set it by calling a method. we need a setter method if we want to be able to do it directly. Like `set_noise` and `get_noise` and using underscore writing approach is very common in a lot of programming languages. In Ruby though, we can make use of that syntactic sugar that we looked at earlier, and so we can take get _out and simply ask for noise. So it asks Animal to do the method noise, which returns the instance variable, noise. It's a very commonsense approach. ``` class Animal def noise=(noise) @noise = noise end def noise @noise end end animal1 = Animal.new animal1.noise = "Moo!" puts animal1.noise animal2 = Animal.new animal2.noise = "Quack!" puts animal2.noise ``` So now` animal1.noise` and `animal2.noise` just returns that to us, where the syntactic sugar comes in is that we can do the same thing with set, we can take away set and just say `noise=(noise).` #### Summary In this tutorial of Advance Ruby Development we learn about the methods, also now we have a better understanding of reading and writing using methods in Ruby. In the next tutorial we will learn about modules and development of our Restaurant Finder App.
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":538746,"name":"ruby","full_name":"ruby/ruby","html_url":"https://github.com/ruby/ruby","fork":false,"owner":{"login":"ruby"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","utopian-io","ruby","app","development"],"users":["noise"]}
Transaction InfoBlock #22048724/Trx afa35db883d9cc6efb12329e91f60cdb7111681f
View Raw JSON Data
{
  "trx_id": "afa35db883d9cc6efb12329e91f60cdb7111681f",
  "block": 22048724,
  "trx_in_block": 40,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-01T12:36:39",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "advance-ruby-development-episode-1",
      "title": "Advance Ruby Development Episode-1",
      "body": "#### Welcome to the First Tutorial of Advance Ruby Development\n<center> <img src= https://imgur.com/MILXLd2.jpg/> </center>\n\n#### What Will I Learn?\n\n- You will learn how to develop Applications using Ruby \n- You will learn about IRB shell in Ruby programming \n- You will learn about various class methods and their usage\n- Your will learn about reading and writing through class methods\n\n\n\n#### Requirements\n##### System Requirements:\n\n- [Ruby Installer]( https://www.ruby-lang.org/en/downloads/) for building apps\n- [SciTE]( https://www.scintilla.org/ScintillaDownload.html) for code editing \n- Command Prompt or Terminal \n##### OS Support:\n\n- Windows 7/8/10\n- macOS \n- Linux \n#### Difficulty\n\n\n\n- Intermediate\n\n#### Required Understanding\n- You just need a little bit of knowledge basic Ruby Syntax\n- A fair understanding of Programming \n- A thirst for learning and developing something new\n\n\n#### Description\n-\tIn this Advance Ruby Development course, I will teach you the advanced concepts of the Ruby programming language. Ruby was designed to be more powerful that Perl, and more object-oriented than Python, and has gained in popularity due to its power and ease of use. By the end of this course you will surely develop some powerful and concrete applications. Also in the end of this course we will be developing a Restaurant finder app.\n\n#### What is Ruby?\nRuby is an object-oriented, general purpose programming language designed by Yukihiro Matsumoto in the 1990s. Intended for improved productivity and entertaining, it creates a great starter language for first time programmers because of its simplicity, readability and concentrate on fun. Commonly used with Rails applications, that is a very popular language that is always in popularity. Organizations such as Twitter and Kickstarter utilize Ruby. \n\n With Ruby, almost everything is an object. Every bit of information as well as codes can be provided their very own attributes and actions. Object-oriented programming calls attributes by the title instance variables and also actions tend to be known as methods. Ruby’s genuine object-oriented approach is quite commonly demonstrated with a bit of code that is applicable an action to a number.\n```\n7.times { print \"I *like* Open Source Projects\" }\n\n```\nAs an example, addition is conducted with the `plus (+)` operator. However, if you would instead use the readable word `plus`, you can add this type of method to Ruby’s builtin Numeric class.\n```\nclass Numeric\n  def plus(x)\n    self.+(x)\n  end\nend\n\ny = 4.plus 3\n\n```\n`which results in the value of y=7\n`\n\nWhat is Interactive Ruby Shell (IRB) ?\nInteractive Ruby Shell (IRB ) is actually a REPL with regard to coding in the Ruby Language. Typically the abbreviation irb originates from the point that the filename extension for Ruby is **.rb**, even though interactive Ruby files don’t have an extension involving **.irb**.\n\nThe program will be launched from the command line and enables the execution of Ruby commands with immediate response, testing in real-time. This features command record, line modifying capabilities, and job control, and it is capable of communicate directly being a shell script on the internet and also connect to a live server.\n`irb [ options ] [ programfile ] [ argument... ] `\n##### Example:\n```\nirb(main):001:0> num = 4\n=> 4\nirb(main):002:0> def fact(num)\nirb(main):003:1>   if num <= 1\nirb(main):004:2>     1\nirb(main):005:2>   else\nirb(main):006:2*     num * fact(num - 1)\nirb(main):007:2>   end\nirb(main):008:1> end\n=> :fact\nirb(main):009:0> fact(num)\n=> 24\n```\n\n\nMethods In Ruby Programming\nRuby uses methods to use a block of codes. In other programming languages some other techniques are used like functions and procedures. Now we will have al look at methods in ruby and then we proceed to the next level.\n\n**Let have a look at this example**\n\n```\ndef welcome\n\tputs \"This course is about Ruby Programming \"\nend\n\ndef add\n\tputs 2 + 3\nend\n\n# Underscore between words, like variable names\ndef longest_word\n  words = ['apple', 'pear', 'banana', 'plum']\n  longest_word = words.inject do |memo,word|\n    memo.length > word.length ? memo : word\n  end\n  puts longest_word\nend\n\n# Method names can have question marks in them\n# Useful for tests and booleans\ndef over_five?\n\tvalue = 3\n\tputs value > 5 ? 'Over 5' : 'Not over 5'\nend\n```\nIn the above example I define four methods which are `welcome,add,longest_word and over_five`\nBehaviour:\n`welcome`: It simply displays a message on the screen which is in this case is “This course is about Ruby Programming ”\n`add`:This method simply perform the addition of two number which is passed as arguments  which are 2 and 3\n`longest_word`: This method does a little interesting job here,it returns me the longest word out of an array of four words by using the `inject` function which accumulates and returns the longest length word by increment the memo each time.\n`over_five?`: This methods basically testing which number is greater between the two and returns the Boolean value. It uses `?`at its end\n#### Reading and Writing Operations:\n\nRuby has methods for Reading and Writing known as Reader and Writer. Other languages have getters and setter for this reading/writing in programs. These methods will allow us to read data from a program or write data to it. Later these operations will help us in making our restaurant finder app. \n#### Example:\n```\nclass Animal\n  def set_noise(noise)\n    @noise = noise\n  end\n  \n  def make_noise\n    @noise\n  end\nend\n\nanimal1 = Animal.new\nanimal1.set_noise(\"Moo!\")\nputs animal1.make_noise\n\nanimal2 = Animal.new\nanimal2.set_noise(\"Quack!\")\nputs animal2.make_noise\n\n```\nNow this is a very common feature of object-oriented programming languages, sometimes in other languages, they're called getter and setter methods. Either one is fine. You can use either name, typically in Ruby, we're going to call them reader and writer methods. So, here is the code which is a perfect example to explain, what we're looking for is a pairing of something that will set a value for us and something that will get a value for us, and that's exactly what we already have with our two methods\n\nThe first one is a setter method or a writer method. So we're setting the value of noise equal to a value, and this is the classic format for what a setter method would look like, `set_noise` equal to a value. It sets it for us. Then we have a  `get_noise`. It's a getter method. The idea is that we are getting that value back. One of these methods sets it, one of them gets it.\nNow the important thing about these two methods is that they give us access control over these instance variables. So for **example**:\n```\nclass Animal\n  def set_noise(noise)\n    @noise = noise\n  end\n  \nanimal1 = Animal.new\nanimal1.set_noise(\"Moo!\")\nputs animal1.make_noise\n\nanimal2 = Animal.new\nanimal2.set_noise(\"Quack!\")\nputs animal2.make_noise\n```\nif we were to take away `get_noise`, now we have no way to get that value back. Of course, we could write another method that would do it for us, but our getter method is gone\n```\nclass Animal\n  \n  def make_noise\n    @noise\n  end\nend\n\nanimal1 = Animal.new\nanimal1.set_noise(\"Moo!\")\nputs animal1.make_noise\n\nanimal2 = Animal.new\nanimal2.set_noise(\"Quack!\")\nputs animal2.make_noise\n```\nSame thing here, if we were to take away `set_noise`, now we have no way to set it by calling a method. we need a setter method if we want to be able to do it directly.\n\nLike `set_noise` and `get_noise` and using underscore writing approach is very common in a lot of programming languages. In Ruby though, we can make use of that syntactic sugar that we looked at earlier, and so we can take get _out and simply ask for noise. So it asks Animal to do the method noise, which returns the instance variable, noise. It's a very commonsense approach. \n```\nclass Animal\n  def noise=(noise)\n    @noise = noise\n  end\n  \n  def noise\n    @noise\n  end\nend\n\nanimal1 = Animal.new\nanimal1.noise = \"Moo!\"\nputs animal1.noise\n\nanimal2 = Animal.new\nanimal2.noise = \"Quack!\"\nputs animal2.noise\n```\nSo now` animal1.noise` and `animal2.noise` just returns that to us, where the syntactic sugar comes in is that we can do the same thing with set, we can take away set and just say `noise=(noise).`\n#### Summary\nIn this tutorial of Advance Ruby Development we learn about the methods, also now we have a better understanding of reading and writing using methods in Ruby. In the next tutorial we will learn about modules and development of our Restaurant Finder App.\n",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":538746,\"name\":\"ruby\",\"full_name\":\"ruby/ruby\",\"html_url\":\"https://github.com/ruby/ruby\",\"fork\":false,\"owner\":{\"login\":\"ruby\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"utopian-io\",\"ruby\",\"app\",\"development\"],\"users\":[\"noise\"]}"
    }
  ]
}
all.carssent 0.001 SBD to @exploringworld- " 🔝UpVote + Resteem Service🔝Get 50-300 Upvotes(1$ - 20$) and Resteem to my 10.800+ followers.Send 1 SBD/1 STEEM to @all.cars ( URL as memo ). 🔥😈🔥Max post age 2 days!"
2018/04/30 22:36:57
fromall.cars
toexploringworld
amount0.001 SBD
memo 🔝UpVote + Resteem Service🔝Get 50-300 Upvotes(1$ - 20$) and Resteem to my 10.800+ followers.Send 1 SBD/1 STEEM to @all.cars ( URL as memo ). 🔥😈🔥Max post age 2 days!
Transaction InfoBlock #22031934/Trx e39723322e2ff4a3e359877dcb1908fc94012bac
View Raw JSON Data
{
  "trx_id": "e39723322e2ff4a3e359877dcb1908fc94012bac",
  "block": 22031934,
  "trx_in_block": 139,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-30T22:36:57",
  "op": [
    "transfer",
    {
      "from": "all.cars",
      "to": "exploringworld",
      "amount": "0.001 SBD",
      "memo": "\t🔝UpVote + Resteem Service🔝Get 50-300 Upvotes(1$ - 20$) and Resteem to my 10.800+ followers.Send 1 SBD/1 STEEM to @all.cars ( URL as memo ). 🔥😈🔥Max post age 2 days!"
    }
  ]
}
2018/04/29 06:25:21
voterclayjohn
authorexploringworld
permlinkbuild-complete-full-stack-web-app-using-go-programming-language
weight10000 (100.00%)
Transaction InfoBlock #21983710/Trx 73575593b1ae56eeb9d1545e45949c56fdce8059
View Raw JSON Data
{
  "trx_id": "73575593b1ae56eeb9d1545e45949c56fdce8059",
  "block": 21983710,
  "trx_in_block": 31,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-29T06:25:21",
  "op": [
    "vote",
    {
      "voter": "clayjohn",
      "author": "exploringworld",
      "permlink": "build-complete-full-stack-web-app-using-go-programming-language",
      "weight": 10000
    }
  ]
}
2018/04/29 04:14:42
parent authorexploringworld
parent permlinkbuild-complete-full-stack-web-app-using-go-programming-language
authoryokunjon
permlinkre-exploringworld-build-complete-full-stack-web-app-using-go-programming-language-20180429t041037964z
title
bodyYour contribution cannot be reviewed because it does not follow the [Utopian Rules](https://utopian.io/rules), and is considered as **plagiarism**. Plagiarism is not allowed on Utopian, and posts that engage in plagiarism will be flagged and hidden forever. * https://www.sohamkamani.com/blog/2017/09/13/how-to-build-a-web-application-in-golang/ Need help? Write a ticket on https://support.utopian.io. Chat with us on [Discord](https://discord.gg/uTyJkNm). **[[utopian-moderator]](https://utopian.io/moderators)**
json metadata{"tags":["utopian-io"],"community":"utopian","app":"utopian/1.0.0"}
Transaction InfoBlock #21981099/Trx f681bbc2f0290e58364c23c0cd505c8484560771
View Raw JSON Data
{
  "trx_id": "f681bbc2f0290e58364c23c0cd505c8484560771",
  "block": 21981099,
  "trx_in_block": 32,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-29T04:14:42",
  "op": [
    "comment",
    {
      "parent_author": "exploringworld",
      "parent_permlink": "build-complete-full-stack-web-app-using-go-programming-language",
      "author": "yokunjon",
      "permlink": "re-exploringworld-build-complete-full-stack-web-app-using-go-programming-language-20180429t041037964z",
      "title": "",
      "body": "Your contribution cannot be reviewed because it does not follow the [Utopian Rules](https://utopian.io/rules), and is considered as **plagiarism**. Plagiarism is not allowed on Utopian, and posts that engage in plagiarism will be flagged and hidden forever.\n\n* https://www.sohamkamani.com/blog/2017/09/13/how-to-build-a-web-application-in-golang/\n\nNeed help? Write a ticket on https://support.utopian.io.\n\nChat with us on [Discord](https://discord.gg/uTyJkNm).\n\n**[[utopian-moderator]](https://utopian.io/moderators)**",
      "json_metadata": "{\"tags\":[\"utopian-io\"],\"community\":\"utopian\",\"app\":\"utopian/1.0.0\"}"
    }
  ]
}
2018/04/29 04:10:09
parent author
parent permlinkutopian-io
authorexploringworld
permlinkbuild-complete-full-stack-web-app-using-go-programming-language
titleBuild Complete Full Stack Web App Using Go Programming Language
body#### Welcome to the First Part of the Tutorial on Build Complete Full Stack Web App Using Go Programming Language <center> <img src= https://imgur.com/Rajc7CQ.jpg/> </center> #### What Will I Learn? - You will learn how to develop full stack web application using Go - You will learn how to create HTTP server and making routes - You will learn about static files and their creation - Your will learn about the REST API handlers and testing #### Requirements ##### System Requirements: - [Go Programming Language]( https://golang.org/dl/) for building App - The Basic Command Line ##### OS Support: - Windows 7/8/10 - macOS - Linux #### Difficulty - Intermediate #### Required Understanding - You just need beginner level understanding of the Go programming language. - A fair understanding of Programming Languages - A thirst for learning and developing something new #### Description - Go gets increasingly more well-known as the go-to language to develop web based applications. - All you need is a little bit of understanding of web design. If you are a web developer and want to build Full Stack Apps, this tutorial is for you.With this particular tutorial, I really hope to get the center ground and provide a single source that explains steps to make a full stack web app in Go, together with adequate test instances. #### What is Go Programming Language ? Go is an open source programming language which makes it simple to develop easy, dependable, and effective software. Go is surely an incredible option for a language as it was developed by a few of the exact same individuals who created the C programming language, Unix, and UTF-8 - probably the most important efforts to computer science. Robert Griesemer, Rob Pike, and Ken Thompson developed Go to become a modern language which easily uses several cores, easily implements concurrency, very easily works in distributed environments, and simply enables the developer to write applications - it has a really lean and user friendly format. #### What is Full Stack ? We will develop a community encyclopedia of animals. This website will : -Display the various records submitted through the community, using the name and information on the animal they will located. -Permit anyone to post a fresh entry about a animal which they found. This application will require three components : 1. The web server 2. The front-end app 3. The database ### Setting up the environment This section explains how you can set up your own environment and project structure the first time #### 1. Set up your $GOPATH Run this command to check the current value of your `$GOPATH `environment variable : `echo $GOPATH` If you do not get a directory name, include the `GOPATH` variable to your environment (you are able to choose any directory location you would like, however it will be much better if you create a brand new directory for this) : `export GOPATH="/location/of/your/gopath/directory"` You can paste the above line in you `.bashrc `or `.zshrc `file, in case you wish to make the variable to be permanent. #### 2. Set up directory structure Hereafter, the actual **“Go directory”** will certainly make reference to the place described from your `$GOPATH` environment variable. Within the Go directory, you will need to create 3 folders (if they happen to be not there previously) : ``` # Inside the Go directory mkdir src mkdir pkg mkdir bin ``` The purpose of each directory can be seen from its name: • bin - is actually wherever all of the executable binaries produced by compiling your code go • pkg - Consists of package objects created by libraries (that you do not have to think about now) • src - is actually wherever all of your Go source code will go. Yes, the whole thing. Even which weird side project that you will be thinking of building. #### 3. Making your project directory The project folders within the src directory must stick to that exact same location structure since the place wherever your remote repository is situated. So, for instance, if I make a new project known as **“animalpedia”**, and i also make a repository for that below my name on github, in a way that the location of the project repository will be on `github.com/exploringworld/animalpedia`, then the place of this project in the computer could be : `$GOPATH/src/github.com/exploringworld/animalpedia` Go on and create a comparable directory for your project. In case you have not created an online repo yet, simply name the directories based on the location which you intend to put your own code in. This particular location on your pc will henceforth become known as your **project directory** ### Getting HTTP server Within your project directory, make a file known as `main.go` inside your project directory : `touch main.go` This particular file will contain the program code to start your server : ```// This is the name of package below // Anything within our this package name can see everything package main // Below are the names of libraries we going to use // Both "fmt" and "net" are part of the Go Language standard library import ( // "fmt" has methods for formatted I/O operations "fmt" // The "net/http" library contains methods to implement HTTP clients and servers "net/http" ) func main() { // The "HandleFunc" method takes a path and a function as arguments // (Yes, we can pass functions as arguments, and even treat them like variables in Go Programming language) // BUT, the handler function has to must have the appropriate signature http.HandleFunc("/", handler) // After we define our server, we now "listen and serve" on port 8080 // The second argument is the handler, which we will come to later on, but for now it is left as nil, // and the handler defined above (in "HandleFunc") is used http.ListenAndServe(":8080", nil) } // "handler" is our handler function. It has to follow the function signature of a ResponseWriter and Request type // as the arguments. func handler(w http.ResponseWriter, r *http.Request) { // For this, we would always pipe the "Hello World" into the response writer fmt.Fprintf(w, "Hello World!") } ``` `fmt.Fprintf,` in contrast to another `printf` statements you might know, requires a “writer” as its 1st argument. The 2nd argument will be the data which is piped in to this writer. The outcome therefore seems based on where the writer goes it. In our situation the `ResponseWriter` w writes the output as the response to users request. ` You now run this file : `go run main.go` And navigate to http://localhost:8080 in your browser, or by running the command through CMD. `curl localhost:8080` And see the code output: **“Hello World!”** You have now successfully started an HTTP server in Go Language. ### Making the routes Our own server is currently operating, but, you may observe that we get exactly the same “Hello World!”response whatever the route we strike, or the HTTP method we utilize. To find out this on your own, run the following curl commands, and take notice of the response that this server will give you : ``` curl localhost:8080/some-other-route curl -X POST localhost:8080 curl -X PUT localhost:8080/samething ``` All three commands are still going to give you “Hello World!” We would like to provide our server a bit more intelligence compared to this, to ensure that we are able to manage a number of paths and methods. This is where routing is necessary. Even though you are able to accomplish this with Go’s `net/http` standard library, there are many libraries available that offer a more idiomatic as well as declarative method to handle http routing. ### Installing external libraries into Go We are setting up a few external libraries through the following tutorial, in which the standard libraries do not give the features that we desire. Whenever we install libraries, we want a way to make sure that others who work with our code also provide exactly the same version of the library that we perform. To do this, we make use of a “package manager” tool. This specific tool acts several purposes: • It ensures the versions associated with any external libraries we all install tend to be locked down, to ensure that breaking changes in some of the libraries usually do not affect our program code. • It brings the necessary external libraries and stores them locally, in order that various projects may use diverse versions of the same library, when they need to. • It stores the names and versions of most our external libraries, so others may set up the same versions which we are working along with on this system. The official package manager for Go (to be more exact “official experiment” which is “safe for production use” as explained on the homepage) is known as dep. You are able to install dep by following the actual setup guide `https://github.com/golang/dep`. You can actually confirm its installation after running : `dep version` which will output a few information on the particular version when successful. In order to load package management for the project, run the command : `dep init` This can produce the` Gopkg.toml` and `Gopkg.lock` files, which are the files which are useful to record and lock dependencies within our project. Next, we set up our routing library: `dep ensure -add github.com/gorilla/mux` This will add the `gorilla/mux` library to your project. Right now, we are able to change the code to work with features this library provides : ``` package main import ( // Import the gorilla/mux library we just installed "fmt" "net/http" "github.com/gorilla/mux" ) func main() { // Declare a new router r := mux.NewRouter() // This is where the router is useful, it allows us to declare methods that // this path will be valid for r.HandleFunc("/hello", handler).Methods("GET") // We can then pass our router (after declaring all our routes) to this method // (where previously, we were leaving the secodn argument as nil) http.ListenAndServe(":8080", r) } func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") } ``` ### Testing Our Application Testing is definitely an important section of building any application **“production quality”**. It makes sure that our app functions like we anticipate that it will. Lets begin by testing our handler. Create a file named main_test.go: ``` //main_test.go package main import ( "net/http" "net/http/httptest" "testing" ) func TestHandler(t *testing.T) { //Here, we form a new HTTP request. This is the request that's going to be // passed to our handler. // The first argument is the method, the second argument is the route (which //we leave blank for now, and will get back to soon), and the third is the //request body, which we don't have in this case. req, err := http.NewRequest("GET", "", nil) // In case there is an error in forming the request, we fail and stop the test if err != nil { t.Fatal(err) } // We use Go's httptest library to create an http recorder. This recorder // will act as the target of our http request // (you can think of it as a mini-browser, which will accept the result of // the http request that we make) recorder := httptest.NewRecorder() // Create an HTTP handler from our handler function. "handler" is the handler // function defined in our main.go file that we want to test hf := http.HandlerFunc(handler) // Serve the HTTP request to our recorder. This is the line that actually // executes our the handler that we want to test hf.ServeHTTP(recorder, req) // Check the status code is what we expect. if status := recorder.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) } // Check the response body is what we expect. expected := `Hello World!` actual := recorder.Body.String() if actual != expected { t.Errorf("handler returned unexpected body: got %v want %v", actual, expected) } } ``` Go utilizes a convention that will determines the test file when it has got the pattern `*_test.go` To perform this test, simply run : go test ./... from the project main directory. You need to see a mild message suggesting that every thing went ok. ### Making our routing to test If you see in our earlier snippet, we kept the **“route”** empty while creating the mock request applying `http.newRequest`. So how exactly does this particular test continue to pass if your handler will be defined just for `“GET /handler”` route? Well, ends up this test was just testing our handler and not the actual routing to the handler. In other words, which means that the above mentioned test makes sure that the request arriving will get functioned properly provided that it is sent to the right handler. In this portion, we are going to test this routing, to ensure that we are able to make sure that every handler will be mapped on the correct HTTP route. Prior to we continue to test our routing, it is essential to ensure that the code can be analyzed for this. Change the main.go file to appear like this: ``` package main import ( "fmt" "net/http" "github.com/gorilla/mux" ) // The new router function creates the router and // returns it to us. We can now use this function // to instantiate and test the router outside of the main function func newRouter() *mux.Router { r := mux.NewRouter() r.HandleFunc("/hello", handler).Methods("GET") return r } func main() { // The router is now formed by calling the `newRouter` constructor function // that we defined above. The rest of the code stays the same r := newRouter() http.ListenAndServe(":8080", r) } func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") } ``` Now our route constructor function is separated, let us see test our routing: ``` func TestRouter(t *testing.T) { // Instantiate the router using the constructor function that // we defined previously r := newRouter() // Create a new server using the "httptest" libraries `NewServer` method // Documentation : https://golang.org/pkg/net/http/httptest/#NewServer mockServer := httptest.NewServer(r) // The mock server we created runs a server and exposes its location in the // URL attribute // We make a GET request to the "hello" route we defined in the router resp, err := http.Get(mockServer.URL + "/hello") // Handle any unexpected error if err != nil { t.Fatal(err) } // We want our status to be 200 (ok) if resp.StatusCode != http.StatusOK { t.Errorf("Status should be ok, got %d", resp.StatusCode) } // In the next few lines, the response body is read, and converted to a string defer resp.Body.Close() // read the body into a bunch of bytes (b) b, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } // convert the bytes to a string respString := string(b) expected := "Hello World!" // We want our response to match the one defined in our handler. // If it does happen to be "Hello world!", then it confirms, that the // route is correct if respString != expected { t.Errorf("Response should be %s, got %s", expected, respString) } } ``` Now we all know that each time we hit the actual `GET /hello route`, we have a response of hello world. When we hit some other route, it should respond having a 404. Actually, let us write a test for exactly this condition : ``` func TestRouterForNonExistentRoute(t *testing.T) { r := newRouter() mockServer := httptest.NewServer(r) // Most of the code is similar. The only difference is that now we make a //request to a route we know we didn't define, like the `POST /hello` route. resp, err := http.Post(mockServer.URL+"/hello", "", nil) if err != nil { t.Fatal(err) } // We want our status to be 405 (method not allowed) if resp.StatusCode != http.StatusMethodNotAllowed { t.Errorf("Status should be 405, got %d", resp.StatusCode) } // The code to test the body is also mostly the same, except this time, we // expect an empty body defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } respString := string(b) expected := "" if respString != expected { t.Errorf("Response should be %s, got %s", expected, respString) } } ``` Since we have figured out how you can make a simple http server, we are able to serve static files from this for the users to interact with. ### Serving the Assets files **“Static files”** are the HTML, CSS, JavaScript, images, and also the additional static asset files which are required to form a web site. You will find 3 actions we must take in so that it will create our server.Now serve these types oo static assets. 1. Make static assets 2. Change our router in order to assist static assets 3. Include tests to confirm our new server can easily serve static files #### Create static assets To create static assets, make a directory in your project root directory, and name it `assets` : `mkdir assets` Following, create an HTML file within this directory. This is actually the file we will serve, together with any file which goes in the assets directory : `touch assets/index.html` #### Modify the router Interestingly sufficient, the whole file server could be enabled in only adding Three lines of code within the router. The newest router constructor may be like this : ``` func newRouter() *mux.Router { r := mux.NewRouter() r.HandleFunc("/hello", handler).Methods("GET") // Declare the static file directory and point it to the // directory we just made staticFileDirectory := http.Dir("./assets/") // Declare the handler, that routes requests to their respective filename. // The fileserver is wrapped in the `stripPrefix` method, because we want to // remove the "/assets/" prefix when looking for files. // For example, if we type "/assets/index.html" in our browser, the file server // will look for only "index.html" inside the directory declared above. // If we did not strip the prefix, the file server would look for // "./assets/assets/index.html", and yield an error staticFileHandler := http.StripPrefix("/assets/", http.FileServer(staticFileDirectory)) // The "PathPrefix" method acts as a matcher, and matches all routes starting // with "/assets/", instead of the absolute route itself r.PathPrefix("/assets/").Handler(staticFileHandler).Methods("GET") return r } ``` #### Testing of static file server It's hard to really say that you will have finished a feature unless you possess tests for it. We can easily check the static file server by having another test function to main_test.go : ``` func TestStaticFileServer(t *testing.T) { r := newRouter() mockServer := httptest.NewServer(r) // We want to hit the `GET /assets/` route to get the index.html file response resp, err := http.Get(mockServer.URL + "/assets/") if err != nil { t.Fatal(err) } // We want our status to be 200 (ok) if resp.StatusCode != http.StatusOK { t.Errorf("Status should be 200, got %d", resp.StatusCode) } // It isn't wise to test the entire content of the HTML file. // Instead, we test that the content-type header is "text/html; charset=utf-8" // so that we know that an html file has been served contentType := resp.Header.Get("Content-Type") expectedContentType := "text/html; charset=utf-8" if expectedContentType != contentType { t.Errorf("Wrong content type, expected %s, got %s", expectedContentType, contentType) } } ``` To actually test your work, run the server : `go run main.go` then, navigate to http://localhost:8080/assets/ in your web browser. #### Making of web browser application Because we have to make our animal encyclopedia, lets make a simple HTML file which shows record of animals, as well as brings the list from an API on-page load, plus offers a form to up-date checklist of animals: ``` <!DOCTYPE html> <html lang="en"> <head> <title>The animal encyclopedia</title> </head> <body> <h1>The animal encyclopedia</h1> <!-- This section of the document specifies the table that will be used to display the list of animals and their description --> <table> <tr> <th>Species</th> <th>Description</th> </tr> <td>Lion</td> <td>Common between cities</td> </tr> </table> <br/> <!-- This section contains the form, that will be used to hit the `POST /animal` API that we will build in the next section --> <form action="/animal" method="post"> Species: <input type="text" name="species"> <br/> Description: <input type="text" name="description"> <br/> <input type="submit" value="Submit"> </form> <!-- Finally, the last section is the script that will run on each page load to fetch the list of animals and add them to our existing table --> <script> animalTable = document.querySelector("table") /* Use the browsers `fetch` API to make a GET call to /animal We expect the response to be a JSON list of animals, of the form : [ {"species":"...","description":"..."}, {"species":"...","description":"..."} ] */ fetch("/animal") .then(response => response.json()) .then(animalList => { //Once we fetch the list, we iterate over it animalList.forEach(animal => { // Create the table row row = document.createElement("tr") // Create the table data elements for the species and // description columns species = document.createElement("td") species.innerHTML = animal.species description = document.createElement("td") description.innerHTML = animal.description // Add the data elements to the row row.appendChild(species) row.appendChild(description) // Finally, add the row element to the table itself animalTable.appendChild(row) }) }) </script> </body> ``` ### Addition of animal REST API handlers We are able to see, we will have to apply 2 APIs to ensure that this app to function: 1. GET /animal - which will retrieve record of all animals presently within the system 2. POST /animal - which will create an entrance to the current set of animals In this, we are going to write the related handlers. Create a new file named animal_handlers.go, next to the main.go file. Initially, we are going to include the definition of the Animal struct as well as initialize a common animal variable: ``` type Animal struct { Species string `json:"species"` Description string `json:"description"` } var animals []Animal ``` Next, define the handler to get all animals : ``` func getAnimalHandler(w http.ResponseWriter, r *http.Request) { //Convert the "animals" variable to json animalListBytes, err := json.Marshal(animals) // If there is an error, print it to the console, and return a server // error response to the user if err != nil { fmt.Println(fmt.Errorf("Error: %v", err)) w.WriteHeader(http.StatusInternalServerError) return } // If all goes well, write the JSON list of animals to the response w.Write(animalListBytes) } ``` Next, the handler to create a new entry of animals : ``` func createAnimalHandler(w http.ResponseWriter, r *http.Request) { // Create a new instance of Animal animal := Animal{} // We send all our data as HTML form data // the `ParseForm` method of the request, parses the // form values err := r.ParseForm() // In case of any error, we respond with an error to the user if err != nil { fmt.Println(fmt.Errorf("Error: %v", err)) w.WriteHeader(http.StatusInternalServerError) return } // Get the information about the animal from the form info animal.Species = r.Form.Get("species") animal.Description = r.Form.Get("description") // Append our existing list of animals with a new entry animals = append(animals, animal) //Finally, we redirect the user to the original HTMl page // (located at `/assets/`), using the http libraries `Redirect` method http.Redirect(w, r, "/assets/", http.StatusFound) } ``` The final stage, is to include these handler to our router, to be able to allow them to use by the app : ``` // These lines are added inside the newRouter() function before returning r r.HandleFunc("/animal", getAnimalHandler).Methods("GET") r.HandleFunc("/animal", createAnimalHandler).Methods("POST") return r ``` The tests regarding the two handlers and also the routing included are similar to the last tests we had written for the GET /hello handler and static file server, and they are still left as an exercise for the readers. ### Summary Up to now, we now have included persistence to the application, using the information about various animals getting saved and retrieved. Nevertheless, that persistence is temporary, because it is in memory space. Which means that at any time you reboot your application, all of the information will get removed. To be able to bring correct persistence, we are going to must add a database to the stack. So far, the code had been simple to reason about and test, as it was obviously a standalone application. Including a database will certainly add an additional layer of communication. We will be going to create a database and connected to our application in the next part of the tutorial <br /><hr/><em>Posted on <a href="https://utopian.io/utopian-io/@exploringworld/build-complete-full-stack-web-app-using-go-programming-language">Utopian.io - Rewarding Open Source Contributors</a></em><hr/>
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":23096959,"name":"go","full_name":"golang/go","html_url":"https://github.com/golang/go","fork":false,"owner":{"login":"golang"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","utopian-io","fullstack","apps","web"],"moderator":{"account":"yokunjon","time":"2018-04-29T04:10:08.976Z","pending":false,"reviewed":false,"flagged":true},"questions":null,"score":null,"total_influence":null,"staff_pick":null,"staff_pick_by":null,"config":{"questions":[{"question":"How many substantial concepts does this tutorial address?","question_id":"tuts-1","answers":[{"answer":"4-5 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-1","value":10},{"answer":"2-3 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-2","value":7},{"answer":"1 substantial concept covered in the tutorial.","answer_id":"tuts-1-a-3","value":3},{"answer":"More than 5 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-4","value":0}]},{"question":"Does the title and the outline of the tutorial properly reflect the content?","question_id":"tuts-2","answers":[{"answer":"Yes, it is very clear.","answer_id":"tuts-2-a-1","value":15},{"answer":"To some extent.","answer_id":"tuts-2-a-2","value":11.5},{"answer":"The title is somewhat misleading and/or the outline is not detailed or informative enough.","answer_id":"tuts-2-a-3","value":4.5},{"answer":"Title and outline are of little or no relevance to the content of the tutorial.","answer_id":"tuts-2-a-4","value":0}]},{"question":"Did the contributor provide supplementary resources, such as code and sample files in the contribution post or a linked GitHub repository?","question_id":"tuts-3","answers":[{"answer":"Yes, exceptional supplementary resources are provided including a relevant github repo/gist.","answer_id":"tuts-3-a-1","value":15},{"answer":"Supplementary resources provided are of high relevance.","answer_id":"tuts-3-a-2","value":12},{"answer":"Contributor provides minimal supplementary resources.","answer_id":"tuts-3-a-3","value":6},{"answer":"No supplementary resources were provided.","answer_id":"tuts-3-a-4","value":0}]},{"question":"Is the tutorial part of a series?","question_id":"tuts-4","answers":[{"answer":"Yes.","answer_id":"tuts-4-a-1","value":10},{"answer":"Yes, but it is the first entry in the series.","answer_id":"tuts-4-a-2","value":7},{"answer":"No, but it works just fine as a stand-alone tutorial.","answer_id":"tuts-4-a-3","value":5},{"answer":"No.","answer_id":"tuts-4-a-4","value":0}]},{"question":"Does the tutorial contain sufficient explanatory visuals?","question_id":"tuts-5","answers":[{"answer":"Yes, the visual components of the post were adequate in quality and quantity.","answer_id":"tuts-5-a-1","value":10},{"answer":"The volume of visual components included was unnecessarily large.","answer_id":"tuts-5-a-2","value":7},{"answer":"The post lacked sufficient visualization to easily learn from the content.","answer_id":"tuts-5-a-3","value":3},{"answer":"No visualization was presented in this contribution.","answer_id":"tuts-5-a-4","value":0}]},{"question":"How unique and/or innovative are the concepts covered in the tutorial?","question_id":"tuts-6","answers":[{"answer":"This was the first time I read about the concepts covered.","answer_id":"tuts-6-a-1","value":10},{"answer":"The concepts covered were innovative and offer some usefulness.","answer_id":"tuts-6-a-2","value":7},{"answer":"I have read several similar ideas and thoughts elsewhere, but this one was of higher quality.","answer_id":"tuts-6-a-3","value":5},{"answer":"Such tutorials can be found online with great ease and the contribution add no value to the open source community.","answer_id":"tuts-6-a-4","value":0}]},{"question":"How would you describe the formatting, language and overall presentation of the post?","question_id":"c-1","answers":[{"answer":"The post is of very high quality.","answer_id":"c-1-a-1","value":10},{"answer":"The post is of decent quality, but not spectacular in any way.","answer_id":"c-1-a-2","value":7},{"answer":"The post is poorly written and/or formatted, but readable.","answer_id":"c-1-a-3","value":3},{"answer":"The post is really hard to read and the content is barely understandable.","answer_id":"c-1-a-4","value":0}]},{"question":"How would you rate the overall value of this contribution on the open source community and ecosystem?","question_id":"c-2","answers":[{"answer":"This contribution brings great and impactful value, and can be used for applications outside the specific project.","answer_id":"c-2-a-1","value":20},{"answer":"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.","answer_id":"c-2-a-2","value":16},{"answer":"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.","answer_id":"c-2-a-3","value":8},{"answer":"This contribution adds no value to the open source community and ecosystem or the specific project.","answer_id":"c-2-a-4","value":0}]}]}}
Transaction InfoBlock #21981008/Trx 74200106b52f48fe85194998d650dc192d5049f1
View Raw JSON Data
{
  "trx_id": "74200106b52f48fe85194998d650dc192d5049f1",
  "block": 21981008,
  "trx_in_block": 33,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-29T04:10:09",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "build-complete-full-stack-web-app-using-go-programming-language",
      "title": "Build Complete Full Stack Web App Using Go Programming Language ",
      "body": "#### Welcome to the First Part of the Tutorial on Build Complete Full Stack Web App Using Go Programming Language \n<center> <img src= https://imgur.com/Rajc7CQ.jpg/> </center>\n\n#### What Will I Learn?\n\n- You will learn how to develop full stack web application using Go\n- You will learn how to create HTTP server and making routes\n- You will learn about static files and their creation\n- Your will learn about the REST API handlers and testing\n\n\n#### Requirements\n##### System Requirements:\n\n- [Go Programming Language]( https://golang.org/dl/) for building App\n- The Basic Command Line\n##### OS Support:\n\n- Windows 7/8/10\n- macOS \n- Linux \n#### Difficulty\n\n\n\n- Intermediate\n\n#### Required Understanding\n- You just need beginner level understanding of the Go programming language.\n- A fair understanding of Programming Languages\n- A thirst for learning and developing something new\n\n\n#### Description\n-\tGo gets increasingly more well-known as the go-to language to develop web based applications.\n-\tAll you need is a little bit of understanding of web design. If you are a web developer and want to build Full Stack Apps, this tutorial is for you.With this particular tutorial, I really hope to get the center ground and provide a single source that explains steps to make a full stack web app in Go, together with adequate test instances.\n#### What is Go Programming Language ?\nGo is an open source programming language which makes it simple to develop easy, dependable, and effective software.\nGo is surely an incredible option for a language as it was developed by a few of the exact same individuals who created the C programming language, Unix, and UTF-8 - probably the most important efforts to computer science. Robert Griesemer, Rob Pike, and Ken Thompson developed Go to become a modern language which easily uses several cores, easily implements concurrency, very easily works in distributed environments, and simply enables the developer to write applications - it has a really lean and user friendly format.\n\n#### What is Full Stack ?\nWe will develop a community encyclopedia of animals. This website will :\n\n-Display the various records submitted through the community, using the name and information on the animal they will located.\n-Permit anyone to post a fresh entry about a animal which they found.\n\nThis application will require three components :\n1.\tThe web server\n2.\tThe front-end app\n3.\tThe database\n### Setting up the environment\nThis section explains how you can set up your own environment and project structure the first time\n\n#### 1. Set up your $GOPATH\nRun this command to check the current value of your `$GOPATH `environment variable :\n`echo $GOPATH`\nIf you do not get a directory name, include the `GOPATH` variable to your environment (you are able to choose any directory location you would like, however it will be much better if you create a brand new directory for this) :\n\n`export GOPATH=\"/location/of/your/gopath/directory\"`\nYou can paste the above line in you `.bashrc `or `.zshrc `file, in case you wish to make the variable to be permanent.\n#### 2. Set up directory structure\nHereafter, the actual **“Go directory”** will certainly make reference to the place described from your `$GOPATH` environment variable. Within the Go directory, you will need to create 3 folders (if they happen to be not there previously) :\n\n```\n# Inside the Go directory\nmkdir src\nmkdir pkg\nmkdir bin\n```\nThe purpose of each directory can be seen from its name:\n• bin - is actually wherever all of the executable binaries produced by compiling your code go\n• pkg - Consists of package objects created by libraries (that you do not have to think about now)\n• src - is actually wherever all of your Go source code will go. Yes, the whole thing. Even which weird side project that you will be thinking of building.\n#### 3. Making your project directory\nThe project folders within the src directory must stick to that exact same location structure since the place wherever your remote repository is situated. So, for instance, if I make a new project known as **“animalpedia”**, and i also make a repository for that below my name on github, in a way that the location of the project repository will be on `github.com/exploringworld/animalpedia`, then the place of this project in the computer could be : \n`$GOPATH/src/github.com/exploringworld/animalpedia`\n\nGo on and create a comparable directory for your project. In case you have not created an online repo yet, simply name the directories based on the location which you intend to put your own code in.\n\nThis particular location on your pc will henceforth become known as your **project directory**\n### Getting HTTP server\n\nWithin your project directory, make a file known as `main.go` inside your project directory :\n\n`touch main.go`\n\nThis particular file will contain the program code to start your server :\n\n```// This is the name of package below\n// Anything within our this package name can see everything\npackage main\n\n// Below are the names of libraries we going to use\n// Both \"fmt\" and \"net\" are part of the Go Language standard library\nimport (\n\t// \"fmt\" has methods for formatted I/O operations\t\"fmt\"\n\t// The \"net/http\" library contains methods to implement HTTP clients and servers\n\t\"net/http\"\n)\n\nfunc main() {\n\t// The \"HandleFunc\" method takes a path and a function as arguments\n\t// (Yes, we can pass functions as arguments, and even treat them like variables in Go Programming language)\n\t// BUT, the handler function has to must have the appropriate signature\n\thttp.HandleFunc(\"/\", handler)\n\n\t// After we define our server, we now \"listen and serve\" on port 8080\n\t// The second argument is the handler, which we will come to later on, but for now it is left as nil,\n\t// and the handler defined above (in \"HandleFunc\") is used\n\thttp.ListenAndServe(\":8080\", nil)\n}\n\n// \"handler\" is our handler function. It has to follow the function signature of a ResponseWriter and Request type\n// as the arguments.\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\t// For this, we would always pipe the \"Hello World\" into the response writer\n\tfmt.Fprintf(w, \"Hello World!\")\n}\n```\n`fmt.Fprintf,` in contrast to another `printf` statements you might know, requires a “writer” as its 1st argument. The 2nd argument will be the data which is piped in to this writer. The outcome therefore seems based on where the writer goes it. In our situation the `ResponseWriter` w writes the output as the response to users request.\n`\n\nYou now run this file :\n`go run main.go`\nAnd navigate to http://localhost:8080 in your browser, or by running the command  through CMD.\n`curl localhost:8080`\nAnd see the code output: **“Hello World!”**\nYou have now successfully started an HTTP server in Go Language.\n### Making the routes\nOur own server is currently operating, but, you may observe that we get exactly the same “Hello World!”response whatever the route we strike, or the HTTP method we utilize. To find out this on your own, run the following curl commands, and take notice of the response that this server will give you :\n```\ncurl localhost:8080/some-other-route\ncurl -X POST localhost:8080\ncurl -X PUT localhost:8080/samething\n```\nAll three commands are still going to give you “Hello World!”\nWe would like to provide our server a bit more intelligence compared to this, to ensure that we are able to manage a number of paths and methods. This is where routing is necessary.\nEven though you are able to accomplish this with Go’s `net/http` standard library, there are many libraries available that offer a more idiomatic as well as declarative method to handle http routing.\n\n### Installing external libraries into Go\nWe are setting up a few external libraries through the following tutorial, in which the standard libraries do not give the features that we desire.\nWhenever we install libraries, we want a way to make sure that others who work with our code also provide exactly the same version of the library that we perform.\nTo do this, we make use of a “package manager” tool. This specific tool acts several purposes:\n•\tIt ensures the versions associated with any external libraries we all install tend to be locked down, to ensure that breaking changes in some of the libraries usually do not affect our program code.\n•\tIt brings the necessary external libraries and stores them locally, in order that various projects may use diverse versions of the same library, when they need to.\n•\tIt stores the names and versions of most our external libraries, so others may set up the same versions which we are working along with on this system.\nThe official package manager for Go (to be more exact “official experiment” which is “safe for production use” as explained on the homepage) is known as dep. You are able to install dep by following the actual setup guide `https://github.com/golang/dep`. You can actually confirm its installation after running :\n\n\n`dep version`\nwhich will output a few information on the particular version when successful.\nIn order to load package management for the project, run the command :\n`dep init`\nThis can produce the` Gopkg.toml` and `Gopkg.lock` files, which are the files which are useful to record and lock dependencies within our project.\nNext, we set up our routing library:\n`dep ensure -add github.com/gorilla/mux`\nThis will add the `gorilla/mux` library to your project.\nRight now, we are able to change the code to work with features this library provides :\n```\npackage main\n\nimport (\n\t// Import the gorilla/mux library we just installed\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/gorilla/mux\"\n)\n\nfunc main() {\n\t// Declare a new router\n\tr := mux.NewRouter()\n\n\t// This is where the router is useful, it allows us to declare methods that\n\t// this path will be valid for\n\tr.HandleFunc(\"/hello\", handler).Methods(\"GET\")\n\n\t// We can then pass our router (after declaring all our routes) to this method\n\t// (where previously, we were leaving the secodn argument as nil)\n\thttp.ListenAndServe(\":8080\", r)\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintf(w, \"Hello World!\")\n}\n```\n### Testing Our Application\nTesting is definitely an important section of building any application **“production quality”**. It makes sure that our app functions like we anticipate that it will.\nLets begin by testing our handler. Create a file named main_test.go:\n```\n//main_test.go\n\npackage main\n\nimport (\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n)\n\nfunc TestHandler(t *testing.T) {\n\t//Here, we form a new HTTP request. This is the request that's going to be\n\t// passed to our handler.\n\t// The first argument is the method, the second argument is the route (which \n\t//we leave blank for now, and will get back to soon), and the third is the \n\t//request body, which we don't have in this case.\n\treq, err := http.NewRequest(\"GET\", \"\", nil)\n\n\t// In case there is an error in forming the request, we fail and stop the test\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We use Go's httptest library to create an http recorder. This recorder\n\t// will act as the target of our http request\n\t// (you can think of it as a mini-browser, which will accept the result of \n\t// the http request that we make)\n\trecorder := httptest.NewRecorder()\n\n\t// Create an HTTP handler from our handler function. \"handler\" is the handler \n\t// function defined in our main.go file that we want to test\n\thf := http.HandlerFunc(handler)\n\n\t// Serve the HTTP request to our recorder. This is the line that actually\n\t// executes our the handler that we want to test\n\thf.ServeHTTP(recorder, req)\n\n\t// Check the status code is what we expect.\n\tif status := recorder.Code; status != http.StatusOK {\n\t\tt.Errorf(\"handler returned wrong status code: got %v want %v\",\n\t\t\tstatus, http.StatusOK)\n\t}\n\n\t// Check the response body is what we expect.\n\texpected := `Hello World!`\n\tactual := recorder.Body.String()\n\tif actual != expected {\n\t\tt.Errorf(\"handler returned unexpected body: got %v want %v\", actual, expected)\n\t}\n}\n```\nGo utilizes a convention that will determines the test file when it has got the pattern `*_test.go`\nTo perform this test, simply run :\ngo test ./...\nfrom the project main directory. You need to see a mild message suggesting that every thing went ok.\n\n### Making our routing to test\nIf you see in our earlier snippet, we kept the **“route”** empty while creating the mock request applying `http.newRequest`. So how exactly does this particular test continue to pass if your handler will be defined just for `“GET /handler”` route?\nWell, ends up this test was just testing our handler and not the actual routing to the handler. In other words, which means that the above mentioned test makes sure that the request arriving will get functioned properly provided that it is sent to the right handler.\nIn this portion, we are going to test this routing, to ensure that we are able to make sure that every handler will be mapped on the correct HTTP route.\nPrior to we continue to test our routing, it is essential to ensure that the code can be analyzed for this. Change the main.go file to appear like this:\n```\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/gorilla/mux\"\n)\n\n// The new router function creates the router and\n// returns it to us. We can now use this function\n// to instantiate and test the router outside of the main function\nfunc newRouter() *mux.Router {\n\tr := mux.NewRouter()\n\tr.HandleFunc(\"/hello\", handler).Methods(\"GET\")\n\treturn r\n}\n\nfunc main() {\n\t// The router is now formed by calling the `newRouter` constructor function\n\t// that we defined above. The rest of the code stays the same\n\tr := newRouter()\n\thttp.ListenAndServe(\":8080\", r)\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintf(w, \"Hello World!\")\n}\n```\nNow  our route constructor function is separated, let us see test our routing:\n```\nfunc TestRouter(t *testing.T) {\n\t// Instantiate the router using the constructor function that\n\t// we defined previously\n\tr := newRouter()\n\n\t// Create a new server using the \"httptest\" libraries `NewServer` method\n\t// Documentation : https://golang.org/pkg/net/http/httptest/#NewServer\n\tmockServer := httptest.NewServer(r)\n\n\t// The mock server we created runs a server and exposes its location in the\n\t// URL attribute\n\t// We make a GET request to the \"hello\" route we defined in the router\n\tresp, err := http.Get(mockServer.URL + \"/hello\")\n\n\t// Handle any unexpected error\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We want our status to be 200 (ok)\n\tif resp.StatusCode != http.StatusOK {\n\t\tt.Errorf(\"Status should be ok, got %d\", resp.StatusCode)\n\t}\n\n\t// In the next few lines, the response body is read, and converted to a string\n\tdefer resp.Body.Close()\n\t// read the body into a bunch of bytes (b)\n\tb, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\t// convert the bytes to a string\n\trespString := string(b)\n\texpected := \"Hello World!\"\n\n\t// We want our response to match the one defined in our handler.\n\t// If it does happen to be \"Hello world!\", then it confirms, that the\n\t// route is correct\n\tif respString != expected {\n\t\tt.Errorf(\"Response should be %s, got %s\", expected, respString)\n\t}\n\n}\n```\nNow we all know that each time we hit the actual `GET /hello route`, we have a response of hello world. When we hit some other route, it should respond having a 404. Actually, let us write a test for exactly this condition :\n```\nfunc TestRouterForNonExistentRoute(t *testing.T) {\n\tr := newRouter()\n\tmockServer := httptest.NewServer(r)\n\t// Most of the code is similar. The only difference is that now we make a \n\t//request to a route we know we didn't define, like the `POST /hello` route.\n\tresp, err := http.Post(mockServer.URL+\"/hello\", \"\", nil)\n\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We want our status to be 405 (method not allowed)\n\tif resp.StatusCode != http.StatusMethodNotAllowed {\n\t\tt.Errorf(\"Status should be 405, got %d\", resp.StatusCode)\n\t}\n\n\t// The code to test the body is also mostly the same, except this time, we \n\t// expect an empty body\n\tdefer resp.Body.Close()\n\tb, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\trespString := string(b)\n\texpected := \"\"\n\n\tif respString != expected {\n\t\tt.Errorf(\"Response should be %s, got %s\", expected, respString)\n\t}\n\n}\n```\nSince we have figured out how you can make a simple http server, we are able to serve static files from this for the users to interact with.\n### Serving the Assets files\n**“Static files”** are the HTML, CSS, JavaScript, images, and also the additional static asset files which are required to form a web site.\nYou will find 3 actions we must take in so that it will create our server.Now serve these types oo static assets.\n1.\tMake static assets\n2.\tChange our router in order to assist static assets\n3.\tInclude tests to confirm our new server can easily serve static files\n#### Create static assets\nTo create static assets, make a directory in your project root directory, and name it `assets` :\n`mkdir assets`\nFollowing, create an HTML file within this directory. This is actually the file we will serve, together with any file which goes in the assets directory :\n`touch assets/index.html`\n#### Modify the router\nInterestingly sufficient, the whole file server could be enabled in only adding Three lines of code within the router. The newest router constructor may be like this :\n```\nfunc newRouter() *mux.Router {\n\tr := mux.NewRouter()\n\tr.HandleFunc(\"/hello\", handler).Methods(\"GET\")\n\n\t// Declare the static file directory and point it to the \n\t// directory we just made\n\tstaticFileDirectory := http.Dir(\"./assets/\")\n\t// Declare the handler, that routes requests to their respective filename.\n\t// The fileserver is wrapped in the `stripPrefix` method, because we want to\n\t// remove the \"/assets/\" prefix when looking for files.\n\t// For example, if we type \"/assets/index.html\" in our browser, the file server\n\t// will look for only \"index.html\" inside the directory declared above.\n\t// If we did not strip the prefix, the file server would look for \n\t// \"./assets/assets/index.html\", and yield an error\n\tstaticFileHandler := http.StripPrefix(\"/assets/\", http.FileServer(staticFileDirectory))\n\t// The \"PathPrefix\" method acts as a matcher, and matches all routes starting\n\t// with \"/assets/\", instead of the absolute route itself\n\tr.PathPrefix(\"/assets/\").Handler(staticFileHandler).Methods(\"GET\")\n\treturn r\n}\n```\n#### Testing of static file server\nIt's hard to really say that you will have finished a feature unless you possess tests for it. We can easily check the static file server by having another test function to main_test.go :\n```\nfunc TestStaticFileServer(t *testing.T) {\n\tr := newRouter()\n\tmockServer := httptest.NewServer(r)\n\n\t// We want to hit the `GET /assets/` route to get the index.html file response\n\tresp, err := http.Get(mockServer.URL + \"/assets/\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We want our status to be 200 (ok)\n\tif resp.StatusCode != http.StatusOK {\n\t\tt.Errorf(\"Status should be 200, got %d\", resp.StatusCode)\n\t}\n\n\t// It isn't wise to test the entire content of the HTML file.\n\t// Instead, we test that the content-type header is \"text/html; charset=utf-8\"\n\t// so that we know that an html file has been served\n\tcontentType := resp.Header.Get(\"Content-Type\")\n\texpectedContentType := \"text/html; charset=utf-8\"\n\n\tif expectedContentType != contentType {\n\t\tt.Errorf(\"Wrong content type, expected %s, got %s\", expectedContentType, contentType)\n\t}\n\n}\n```\nTo actually test your work, run the server :\n`go run main.go`\nthen, navigate to http://localhost:8080/assets/ in your web browser.\n#### Making of web browser application\nBecause we have to make our animal encyclopedia, lets make a simple HTML file which shows record of animals, as well as brings the list from an API on-page load, plus offers a form to up-date checklist of animals:\n```\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <title>The animal encyclopedia</title>\n</head>\n\n<body>\n  <h1>The animal encyclopedia</h1>\n  <!-- \n    This section of the document specifies the table that will\n    be used to display the list of animals and their description\n   -->\n  <table>\n    <tr>\n      <th>Species</th>\n      <th>Description</th>\n    </tr>\n    <td>Lion</td>\n    <td>Common between cities</td>\n    </tr>\n  </table>\n  <br/>\n\n  <!-- \n    This section contains the form, that will be used to hit the \n    `POST /animal` API that we will build in the next section\n   -->\n  <form action=\"/animal\" method=\"post\">\n    Species:\n    <input type=\"text\" name=\"species\">\n    <br/> Description:\n    <input type=\"text\" name=\"description\">\n    <br/>\n    <input type=\"submit\" value=\"Submit\">\n  </form>\n\n  <!-- \n    Finally, the last section is the script that will\n    run on each page load to fetch the list of animals\n    and add them to our existing table\n   -->\n  <script>\n    animalTable = document.querySelector(\"table\")\n\n    /*\n    Use the browsers `fetch` API to make a GET call to /animal\n    We expect the response to be a JSON list of animals, of the\n    form :\n    [\n      {\"species\":\"...\",\"description\":\"...\"},\n      {\"species\":\"...\",\"description\":\"...\"}\n    ]\n    */\n    fetch(\"/animal\")\n      .then(response => response.json())\n      .then(animalList => {\n        //Once we fetch the list, we iterate over it\n        animalList.forEach(animal => {\n          // Create the table row\n          row = document.createElement(\"tr\")\n\n          // Create the table data elements for the species and\n\t\t\t\t\t// description columns\n          species = document.createElement(\"td\")\n          species.innerHTML = animal.species\n          description = document.createElement(\"td\")\n          description.innerHTML = animal.description\n\n          // Add the data elements to the row\n          row.appendChild(species)\n          row.appendChild(description)\n          // Finally, add the row element to the table itself\n          animalTable.appendChild(row)\n        })\n      })\n  </script>\n</body>\n```\n### Addition of animal REST API handlers\nWe are able to see, we will have to apply 2 APIs to ensure that this app to function:\n1. GET /animal - which will retrieve record of all animals presently within the system\n2. POST /animal - which will create an entrance to the current set of animals\nIn this, we are going to write the related handlers.\nCreate a new file named animal_handlers.go, next to the main.go file.\nInitially, we are going to include the definition of the Animal struct as well as initialize a common animal variable:\n```\ntype Animal struct {\n\tSpecies     string `json:\"species\"`\n\tDescription string `json:\"description\"`\n}\n\nvar animals []Animal\n```\nNext, define the handler to get all animals :\n```\nfunc getAnimalHandler(w http.ResponseWriter, r *http.Request) {\n\t//Convert the \"animals\" variable to json\n\tanimalListBytes, err := json.Marshal(animals)\n\n\t// If there is an error, print it to the console, and return a server\n\t// error response to the user\n\tif err != nil {\n\t\tfmt.Println(fmt.Errorf(\"Error: %v\", err))\n\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\treturn\n\t}\n\t// If all goes well, write the JSON list of animals to the response\n\tw.Write(animalListBytes)\n}\n```\nNext, the handler to create a new entry of animals :\n```\nfunc createAnimalHandler(w http.ResponseWriter, r *http.Request) {\n\t// Create a new instance of Animal\n\tanimal := Animal{}\n\n\t// We send all our data as HTML form data\n\t// the `ParseForm` method of the request, parses the\n\t// form values\n\terr := r.ParseForm()\n\n\t// In case of any error, we respond with an error to the user\n\tif err != nil {\n\t\tfmt.Println(fmt.Errorf(\"Error: %v\", err))\n\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\t// Get the information about the animal from the form info\n\tanimal.Species = r.Form.Get(\"species\")\n\tanimal.Description = r.Form.Get(\"description\")\n\n\t// Append our existing list of animals with a new entry\n\tanimals = append(animals, animal)\n\n\t//Finally, we redirect the user to the original HTMl page\n\t// (located at `/assets/`), using the http libraries `Redirect` method\n\thttp.Redirect(w, r, \"/assets/\", http.StatusFound)\n}\n```\nThe final stage, is to include these handler to our router, to be able to allow them to use by the app :\n```\n\t// These lines are added inside the newRouter() function before returning r\n\tr.HandleFunc(\"/animal\", getAnimalHandler).Methods(\"GET\")\n\tr.HandleFunc(\"/animal\", createAnimalHandler).Methods(\"POST\")\n\treturn r\n```\nThe tests regarding the two handlers and also the routing included are similar to the last tests we had written for the GET /hello handler and static file server, and they are still left as an exercise for the readers.\n\n### Summary\nUp to now, we now have included persistence to the application, using the information about various animals getting saved and retrieved.\nNevertheless, that persistence is temporary, because it is in memory space. Which means that at any time you reboot your application, all of the information will get removed. To be able to bring correct persistence, we are going to must add a database to the stack.\nSo far, the code had been simple to reason about and test, as it was obviously a standalone application. Including a database will certainly add an additional layer of communication.\nWe will be going to create a database and connected to our application in the next part of the tutorial\n\n\n<br /><hr/><em>Posted on <a href=\"https://utopian.io/utopian-io/@exploringworld/build-complete-full-stack-web-app-using-go-programming-language\">Utopian.io -  Rewarding Open Source Contributors</a></em><hr/>",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":23096959,\"name\":\"go\",\"full_name\":\"golang/go\",\"html_url\":\"https://github.com/golang/go\",\"fork\":false,\"owner\":{\"login\":\"golang\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"utopian-io\",\"fullstack\",\"apps\",\"web\"],\"moderator\":{\"account\":\"yokunjon\",\"time\":\"2018-04-29T04:10:08.976Z\",\"pending\":false,\"reviewed\":false,\"flagged\":true},\"questions\":null,\"score\":null,\"total_influence\":null,\"staff_pick\":null,\"staff_pick_by\":null,\"config\":{\"questions\":[{\"question\":\"How many substantial concepts does this tutorial address?\",\"question_id\":\"tuts-1\",\"answers\":[{\"answer\":\"4-5 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-1\",\"value\":10},{\"answer\":\"2-3 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-2\",\"value\":7},{\"answer\":\"1 substantial concept covered in the tutorial.\",\"answer_id\":\"tuts-1-a-3\",\"value\":3},{\"answer\":\"More than 5 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-4\",\"value\":0}]},{\"question\":\"Does the title and the outline of the tutorial properly reflect the content?\",\"question_id\":\"tuts-2\",\"answers\":[{\"answer\":\"Yes, it is very clear.\",\"answer_id\":\"tuts-2-a-1\",\"value\":15},{\"answer\":\"To some extent.\",\"answer_id\":\"tuts-2-a-2\",\"value\":11.5},{\"answer\":\"The title is somewhat misleading and/or the outline is not detailed or informative enough.\",\"answer_id\":\"tuts-2-a-3\",\"value\":4.5},{\"answer\":\"Title and outline are of little or no relevance to the content of the tutorial.\",\"answer_id\":\"tuts-2-a-4\",\"value\":0}]},{\"question\":\"Did the contributor provide supplementary resources, such as code and sample files in the contribution post or a linked GitHub repository?\",\"question_id\":\"tuts-3\",\"answers\":[{\"answer\":\"Yes, exceptional supplementary resources are provided including a relevant github repo/gist.\",\"answer_id\":\"tuts-3-a-1\",\"value\":15},{\"answer\":\"Supplementary resources provided are of high relevance.\",\"answer_id\":\"tuts-3-a-2\",\"value\":12},{\"answer\":\"Contributor provides minimal supplementary resources.\",\"answer_id\":\"tuts-3-a-3\",\"value\":6},{\"answer\":\"No supplementary resources were provided.\",\"answer_id\":\"tuts-3-a-4\",\"value\":0}]},{\"question\":\"Is the tutorial part of a series?\",\"question_id\":\"tuts-4\",\"answers\":[{\"answer\":\"Yes.\",\"answer_id\":\"tuts-4-a-1\",\"value\":10},{\"answer\":\"Yes, but it is the first entry in the series.\",\"answer_id\":\"tuts-4-a-2\",\"value\":7},{\"answer\":\"No, but it works just fine as a stand-alone tutorial.\",\"answer_id\":\"tuts-4-a-3\",\"value\":5},{\"answer\":\"No.\",\"answer_id\":\"tuts-4-a-4\",\"value\":0}]},{\"question\":\"Does the tutorial contain sufficient explanatory visuals?\",\"question_id\":\"tuts-5\",\"answers\":[{\"answer\":\"Yes, the visual components of the post were adequate in quality and quantity.\",\"answer_id\":\"tuts-5-a-1\",\"value\":10},{\"answer\":\"The volume of visual components included was unnecessarily large.\",\"answer_id\":\"tuts-5-a-2\",\"value\":7},{\"answer\":\"The post lacked sufficient visualization to easily learn from the content.\",\"answer_id\":\"tuts-5-a-3\",\"value\":3},{\"answer\":\"No visualization was presented in this contribution.\",\"answer_id\":\"tuts-5-a-4\",\"value\":0}]},{\"question\":\"How unique and/or innovative are the concepts covered in the tutorial?\",\"question_id\":\"tuts-6\",\"answers\":[{\"answer\":\"This was the first time I read about the concepts covered.\",\"answer_id\":\"tuts-6-a-1\",\"value\":10},{\"answer\":\"The concepts covered were innovative and offer some usefulness.\",\"answer_id\":\"tuts-6-a-2\",\"value\":7},{\"answer\":\"I have read several similar ideas and thoughts elsewhere, but this one was of higher quality.\",\"answer_id\":\"tuts-6-a-3\",\"value\":5},{\"answer\":\"Such tutorials can be found online with great ease and the contribution add no value to the open source community.\",\"answer_id\":\"tuts-6-a-4\",\"value\":0}]},{\"question\":\"How would you describe the formatting, language and overall presentation of the post?\",\"question_id\":\"c-1\",\"answers\":[{\"answer\":\"The post is of very high quality.\",\"answer_id\":\"c-1-a-1\",\"value\":10},{\"answer\":\"The post is of decent quality, but not spectacular in any way.\",\"answer_id\":\"c-1-a-2\",\"value\":7},{\"answer\":\"The post is poorly written and/or formatted, but readable.\",\"answer_id\":\"c-1-a-3\",\"value\":3},{\"answer\":\"The post is really hard to read and the content is barely understandable.\",\"answer_id\":\"c-1-a-4\",\"value\":0}]},{\"question\":\"How would you rate the overall value of this contribution on the open source community and ecosystem?\",\"question_id\":\"c-2\",\"answers\":[{\"answer\":\"This contribution brings great and impactful value, and can be used for applications outside the specific project.\",\"answer_id\":\"c-2-a-1\",\"value\":20},{\"answer\":\"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.\",\"answer_id\":\"c-2-a-2\",\"value\":16},{\"answer\":\"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.\",\"answer_id\":\"c-2-a-3\",\"value\":8},{\"answer\":\"This contribution adds no value to the open source community and ecosystem or the specific project.\",\"answer_id\":\"c-2-a-4\",\"value\":0}]}]}}"
    }
  ]
}
2018/04/29 03:44:33
parent author
parent permlinkutopian-io
authorexploringworld
permlinkbuild-complete-full-stack-web-app-using-go-programming-language
titleBuild Complete Full Stack Web App Using Go Programming Language
body#### Welcome to the First Part of the Tutorial on Build Complete Full Stack Web App Using Go Programming Language <center> <img src= https://imgur.com/Rajc7CQ.jpg/> </center> #### What Will I Learn? - You will learn how to develop full stack web application using Go - You will learn how to create HTTP server and making routes - You will learn about static files and their creation - Your will learn about the REST API handlers and testing #### Requirements ##### System Requirements: - [Go Programming Language]( https://golang.org/dl/) for building App - The Basic Command Line ##### OS Support: - Windows 7/8/10 - macOS - Linux #### Difficulty - Intermediate #### Required Understanding - You just need beginner level understanding of the Go programming language. - A fair understanding of Programming Languages - A thirst for learning and developing something new #### Description - Go gets increasingly more well-known as the go-to language to develop web based applications. - All you need is a little bit of understanding of web design. If you are a web developer and want to build Full Stack Apps, this tutorial is for you.With this particular tutorial, I really hope to get the center ground and provide a single source that explains steps to make a full stack web app in Go, together with adequate test instances. #### What is Go Programming Language ? Go is an open source programming language which makes it simple to develop easy, dependable, and effective software. Go is surely an incredible option for a language as it was developed by a few of the exact same individuals who created the C programming language, Unix, and UTF-8 - probably the most important efforts to computer science. Robert Griesemer, Rob Pike, and Ken Thompson developed Go to become a modern language which easily uses several cores, easily implements concurrency, very easily works in distributed environments, and simply enables the developer to write applications - it has a really lean and user friendly format. #### What is Full Stack ? We will develop a community encyclopedia of animals. This website will : -Display the various records submitted through the community, using the name and information on the animal they will located. -Permit anyone to post a fresh entry about a animal which they found. This application will require three components : 1. The web server 2. The front-end app 3. The database ### Setting up the environment This section explains how you can set up your own environment and project structure the first time #### 1. Set up your $GOPATH Run this command to check the current value of your `$GOPATH `environment variable : `echo $GOPATH` If you do not get a directory name, include the `GOPATH` variable to your environment (you are able to choose any directory location you would like, however it will be much better if you create a brand new directory for this) : `export GOPATH="/location/of/your/gopath/directory"` You can paste the above line in you `.bashrc `or `.zshrc `file, in case you wish to make the variable to be permanent. #### 2. Set up directory structure Hereafter, the actual **“Go directory”** will certainly make reference to the place described from your `$GOPATH` environment variable. Within the Go directory, you will need to create 3 folders (if they happen to be not there previously) : ``` # Inside the Go directory mkdir src mkdir pkg mkdir bin ``` The purpose of each directory can be seen from its name: • bin - is actually wherever all of the executable binaries produced by compiling your code go • pkg - Consists of package objects created by libraries (that you do not have to think about now) • src - is actually wherever all of your Go source code will go. Yes, the whole thing. Even which weird side project that you will be thinking of building. #### 3. Making your project directory The project folders within the src directory must stick to that exact same location structure since the place wherever your remote repository is situated. So, for instance, if I make a new project known as **“animalpedia”**, and i also make a repository for that below my name on github, in a way that the location of the project repository will be on `github.com/exploringworld/animalpedia`, then the place of this project in the computer could be : `$GOPATH/src/github.com/exploringworld/animalpedia` Go on and create a comparable directory for your project. In case you have not created an online repo yet, simply name the directories based on the location which you intend to put your own code in. This particular location on your pc will henceforth become known as your **project directory** ### Getting HTTP server Within your project directory, make a file known as `main.go` inside your project directory : `touch main.go` This particular file will contain the program code to start your server : ```// This is the name of package below // Anything within our this package name can see everything package main // Below are the names of libraries we going to use // Both "fmt" and "net" are part of the Go Language standard library import ( // "fmt" has methods for formatted I/O operations "fmt" // The "net/http" library contains methods to implement HTTP clients and servers "net/http" ) func main() { // The "HandleFunc" method takes a path and a function as arguments // (Yes, we can pass functions as arguments, and even treat them like variables in Go Programming language) // BUT, the handler function has to must have the appropriate signature http.HandleFunc("/", handler) // After we define our server, we now "listen and serve" on port 8080 // The second argument is the handler, which we will come to later on, but for now it is left as nil, // and the handler defined above (in "HandleFunc") is used http.ListenAndServe(":8080", nil) } // "handler" is our handler function. It has to follow the function signature of a ResponseWriter and Request type // as the arguments. func handler(w http.ResponseWriter, r *http.Request) { // For this, we would always pipe the "Hello World" into the response writer fmt.Fprintf(w, "Hello World!") } ``` `fmt.Fprintf,` in contrast to another `printf` statements you might know, requires a “writer” as its 1st argument. The 2nd argument will be the data which is piped in to this writer. The outcome therefore seems based on where the writer goes it. In our situation the `ResponseWriter` w writes the output as the response to users request. ` You now run this file : `go run main.go` And navigate to http://localhost:8080 in your browser, or by running the command through CMD. `curl localhost:8080` And see the code output: **“Hello World!”** You have now successfully started an HTTP server in Go Language. ### Making the routes Our own server is currently operating, but, you may observe that we get exactly the same “Hello World!”response whatever the route we strike, or the HTTP method we utilize. To find out this on your own, run the following curl commands, and take notice of the response that this server will give you : ``` curl localhost:8080/some-other-route curl -X POST localhost:8080 curl -X PUT localhost:8080/samething ``` All three commands are still going to give you “Hello World!” We would like to provide our server a bit more intelligence compared to this, to ensure that we are able to manage a number of paths and methods. This is where routing is necessary. Even though you are able to accomplish this with Go’s `net/http` standard library, there are many libraries available that offer a more idiomatic as well as declarative method to handle http routing. ### Installing external libraries into Go We are setting up a few external libraries through the following tutorial, in which the standard libraries do not give the features that we desire. Whenever we install libraries, we want a way to make sure that others who work with our code also provide exactly the same version of the library that we perform. To do this, we make use of a “package manager” tool. This specific tool acts several purposes: • It ensures the versions associated with any external libraries we all install tend to be locked down, to ensure that breaking changes in some of the libraries usually do not affect our program code. • It brings the necessary external libraries and stores them locally, in order that various projects may use diverse versions of the same library, when they need to. • It stores the names and versions of most our external libraries, so others may set up the same versions which we are working along with on this system. The official package manager for Go (to be more exact “official experiment” which is “safe for production use” as explained on the homepage) is known as dep. You are able to install dep by following the actual setup guide `https://github.com/golang/dep`. You can actually confirm its installation after running : `dep version` which will output a few information on the particular version when successful. In order to load package management for the project, run the command : `dep init` This can produce the` Gopkg.toml` and `Gopkg.lock` files, which are the files which are useful to record and lock dependencies within our project. Next, we set up our routing library: `dep ensure -add github.com/gorilla/mux` This will add the `gorilla/mux` library to your project. Right now, we are able to change the code to work with features this library provides : ``` package main import ( // Import the gorilla/mux library we just installed "fmt" "net/http" "github.com/gorilla/mux" ) func main() { // Declare a new router r := mux.NewRouter() // This is where the router is useful, it allows us to declare methods that // this path will be valid for r.HandleFunc("/hello", handler).Methods("GET") // We can then pass our router (after declaring all our routes) to this method // (where previously, we were leaving the secodn argument as nil) http.ListenAndServe(":8080", r) } func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") } ``` ### Testing Our Application Testing is definitely an important section of building any application **“production quality”**. It makes sure that our app functions like we anticipate that it will. Lets begin by testing our handler. Create a file named main_test.go: ``` //main_test.go package main import ( "net/http" "net/http/httptest" "testing" ) func TestHandler(t *testing.T) { //Here, we form a new HTTP request. This is the request that's going to be // passed to our handler. // The first argument is the method, the second argument is the route (which //we leave blank for now, and will get back to soon), and the third is the //request body, which we don't have in this case. req, err := http.NewRequest("GET", "", nil) // In case there is an error in forming the request, we fail and stop the test if err != nil { t.Fatal(err) } // We use Go's httptest library to create an http recorder. This recorder // will act as the target of our http request // (you can think of it as a mini-browser, which will accept the result of // the http request that we make) recorder := httptest.NewRecorder() // Create an HTTP handler from our handler function. "handler" is the handler // function defined in our main.go file that we want to test hf := http.HandlerFunc(handler) // Serve the HTTP request to our recorder. This is the line that actually // executes our the handler that we want to test hf.ServeHTTP(recorder, req) // Check the status code is what we expect. if status := recorder.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) } // Check the response body is what we expect. expected := `Hello World!` actual := recorder.Body.String() if actual != expected { t.Errorf("handler returned unexpected body: got %v want %v", actual, expected) } } ``` Go utilizes a convention that will determines the test file when it has got the pattern `*_test.go` To perform this test, simply run : go test ./... from the project main directory. You need to see a mild message suggesting that every thing went ok. ### Making our routing to test If you see in our earlier snippet, we kept the **“route”** empty while creating the mock request applying `http.newRequest`. So how exactly does this particular test continue to pass if your handler will be defined just for `“GET /handler”` route? Well, ends up this test was just testing our handler and not the actual routing to the handler. In other words, which means that the above mentioned test makes sure that the request arriving will get functioned properly provided that it is sent to the right handler. In this portion, we are going to test this routing, to ensure that we are able to make sure that every handler will be mapped on the correct HTTP route. Prior to we continue to test our routing, it is essential to ensure that the code can be analyzed for this. Change the main.go file to appear like this: ``` package main import ( "fmt" "net/http" "github.com/gorilla/mux" ) // The new router function creates the router and // returns it to us. We can now use this function // to instantiate and test the router outside of the main function func newRouter() *mux.Router { r := mux.NewRouter() r.HandleFunc("/hello", handler).Methods("GET") return r } func main() { // The router is now formed by calling the `newRouter` constructor function // that we defined above. The rest of the code stays the same r := newRouter() http.ListenAndServe(":8080", r) } func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") } ``` Now our route constructor function is separated, let us see test our routing: ``` func TestRouter(t *testing.T) { // Instantiate the router using the constructor function that // we defined previously r := newRouter() // Create a new server using the "httptest" libraries `NewServer` method // Documentation : https://golang.org/pkg/net/http/httptest/#NewServer mockServer := httptest.NewServer(r) // The mock server we created runs a server and exposes its location in the // URL attribute // We make a GET request to the "hello" route we defined in the router resp, err := http.Get(mockServer.URL + "/hello") // Handle any unexpected error if err != nil { t.Fatal(err) } // We want our status to be 200 (ok) if resp.StatusCode != http.StatusOK { t.Errorf("Status should be ok, got %d", resp.StatusCode) } // In the next few lines, the response body is read, and converted to a string defer resp.Body.Close() // read the body into a bunch of bytes (b) b, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } // convert the bytes to a string respString := string(b) expected := "Hello World!" // We want our response to match the one defined in our handler. // If it does happen to be "Hello world!", then it confirms, that the // route is correct if respString != expected { t.Errorf("Response should be %s, got %s", expected, respString) } } ``` Now we all know that each time we hit the actual `GET /hello route`, we have a response of hello world. When we hit some other route, it should respond having a 404. Actually, let us write a test for exactly this condition : ``` func TestRouterForNonExistentRoute(t *testing.T) { r := newRouter() mockServer := httptest.NewServer(r) // Most of the code is similar. The only difference is that now we make a //request to a route we know we didn't define, like the `POST /hello` route. resp, err := http.Post(mockServer.URL+"/hello", "", nil) if err != nil { t.Fatal(err) } // We want our status to be 405 (method not allowed) if resp.StatusCode != http.StatusMethodNotAllowed { t.Errorf("Status should be 405, got %d", resp.StatusCode) } // The code to test the body is also mostly the same, except this time, we // expect an empty body defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } respString := string(b) expected := "" if respString != expected { t.Errorf("Response should be %s, got %s", expected, respString) } } ``` Since we have figured out how you can make a simple http server, we are able to serve static files from this for the users to interact with. ### Serving the Assets files **“Static files”** are the HTML, CSS, JavaScript, images, and also the additional static asset files which are required to form a web site. You will find 3 actions we must take in so that it will create our server.Now serve these types oo static assets. 1. Make static assets 2. Change our router in order to assist static assets 3. Include tests to confirm our new server can easily serve static files #### Create static assets To create static assets, make a directory in your project root directory, and name it `assets` : `mkdir assets` Following, create an HTML file within this directory. This is actually the file we will serve, together with any file which goes in the assets directory : `touch assets/index.html` #### Modify the router Interestingly sufficient, the whole file server could be enabled in only adding Three lines of code within the router. The newest router constructor may be like this : ``` func newRouter() *mux.Router { r := mux.NewRouter() r.HandleFunc("/hello", handler).Methods("GET") // Declare the static file directory and point it to the // directory we just made staticFileDirectory := http.Dir("./assets/") // Declare the handler, that routes requests to their respective filename. // The fileserver is wrapped in the `stripPrefix` method, because we want to // remove the "/assets/" prefix when looking for files. // For example, if we type "/assets/index.html" in our browser, the file server // will look for only "index.html" inside the directory declared above. // If we did not strip the prefix, the file server would look for // "./assets/assets/index.html", and yield an error staticFileHandler := http.StripPrefix("/assets/", http.FileServer(staticFileDirectory)) // The "PathPrefix" method acts as a matcher, and matches all routes starting // with "/assets/", instead of the absolute route itself r.PathPrefix("/assets/").Handler(staticFileHandler).Methods("GET") return r } ``` #### Testing of static file server It's hard to really say that you will have finished a feature unless you possess tests for it. We can easily check the static file server by having another test function to main_test.go : ``` func TestStaticFileServer(t *testing.T) { r := newRouter() mockServer := httptest.NewServer(r) // We want to hit the `GET /assets/` route to get the index.html file response resp, err := http.Get(mockServer.URL + "/assets/") if err != nil { t.Fatal(err) } // We want our status to be 200 (ok) if resp.StatusCode != http.StatusOK { t.Errorf("Status should be 200, got %d", resp.StatusCode) } // It isn't wise to test the entire content of the HTML file. // Instead, we test that the content-type header is "text/html; charset=utf-8" // so that we know that an html file has been served contentType := resp.Header.Get("Content-Type") expectedContentType := "text/html; charset=utf-8" if expectedContentType != contentType { t.Errorf("Wrong content type, expected %s, got %s", expectedContentType, contentType) } } ``` To actually test your work, run the server : `go run main.go` then, navigate to http://localhost:8080/assets/ in your web browser. #### Making of web browser application Because we have to make our animal encyclopedia, lets make a simple HTML file which shows record of animals, as well as brings the list from an API on-page load, plus offers a form to up-date checklist of animals: ``` <!DOCTYPE html> <html lang="en"> <head> <title>The animal encyclopedia</title> </head> <body> <h1>The animal encyclopedia</h1> <!-- This section of the document specifies the table that will be used to display the list of animals and their description --> <table> <tr> <th>Species</th> <th>Description</th> </tr> <td>Lion</td> <td>Common between cities</td> </tr> </table> <br/> <!-- This section contains the form, that will be used to hit the `POST /animal` API that we will build in the next section --> <form action="/animal" method="post"> Species: <input type="text" name="species"> <br/> Description: <input type="text" name="description"> <br/> <input type="submit" value="Submit"> </form> <!-- Finally, the last section is the script that will run on each page load to fetch the list of animals and add them to our existing table --> <script> animalTable = document.querySelector("table") /* Use the browsers `fetch` API to make a GET call to /animal We expect the response to be a JSON list of animals, of the form : [ {"species":"...","description":"..."}, {"species":"...","description":"..."} ] */ fetch("/animal") .then(response => response.json()) .then(animalList => { //Once we fetch the list, we iterate over it animalList.forEach(animal => { // Create the table row row = document.createElement("tr") // Create the table data elements for the species and // description columns species = document.createElement("td") species.innerHTML = animal.species description = document.createElement("td") description.innerHTML = animal.description // Add the data elements to the row row.appendChild(species) row.appendChild(description) // Finally, add the row element to the table itself animalTable.appendChild(row) }) }) </script> </body> ``` ### Addition of animal REST API handlers We are able to see, we will have to apply 2 APIs to ensure that this app to function: 1. GET /animal - which will retrieve record of all animals presently within the system 2. POST /animal - which will create an entrance to the current set of animals In this, we are going to write the related handlers. Create a new file named animal_handlers.go, next to the main.go file. Initially, we are going to include the definition of the Animal struct as well as initialize a common animal variable: ``` type Animal struct { Species string `json:"species"` Description string `json:"description"` } var animals []Animal ``` Next, define the handler to get all animals : ``` func getAnimalHandler(w http.ResponseWriter, r *http.Request) { //Convert the "animals" variable to json animalListBytes, err := json.Marshal(animals) // If there is an error, print it to the console, and return a server // error response to the user if err != nil { fmt.Println(fmt.Errorf("Error: %v", err)) w.WriteHeader(http.StatusInternalServerError) return } // If all goes well, write the JSON list of animals to the response w.Write(animalListBytes) } ``` Next, the handler to create a new entry of animals : ``` func createAnimalHandler(w http.ResponseWriter, r *http.Request) { // Create a new instance of Animal animal := Animal{} // We send all our data as HTML form data // the `ParseForm` method of the request, parses the // form values err := r.ParseForm() // In case of any error, we respond with an error to the user if err != nil { fmt.Println(fmt.Errorf("Error: %v", err)) w.WriteHeader(http.StatusInternalServerError) return } // Get the information about the animal from the form info animal.Species = r.Form.Get("species") animal.Description = r.Form.Get("description") // Append our existing list of animals with a new entry animals = append(animals, animal) //Finally, we redirect the user to the original HTMl page // (located at `/assets/`), using the http libraries `Redirect` method http.Redirect(w, r, "/assets/", http.StatusFound) } ``` The final stage, is to include these handler to our router, to be able to allow them to use by the app : ``` // These lines are added inside the newRouter() function before returning r r.HandleFunc("/animal", getAnimalHandler).Methods("GET") r.HandleFunc("/animal", createAnimalHandler).Methods("POST") return r ``` The tests regarding the two handlers and also the routing included are similar to the last tests we had written for the GET /hello handler and static file server, and they are still left as an exercise for the readers. ### Summary Up to now, we now have included persistence to the application, using the information about various animals getting saved and retrieved. Nevertheless, that persistence is temporary, because it is in memory space. Which means that at any time you reboot your application, all of the information will get removed. To be able to bring correct persistence, we are going to must add a database to the stack. So far, the code had been simple to reason about and test, as it was obviously a standalone application. Including a database will certainly add an additional layer of communication. We will be going to create a database and connected to our application in the next part of the tutorial <br /><hr/><em>Posted on <a href="https://utopian.io/utopian-io/@exploringworld/build-complete-full-stack-web-app-using-go-programming-language">Utopian.io - Rewarding Open Source Contributors</a></em><hr/>
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":23096959,"name":"go","full_name":"golang/go","html_url":"https://github.com/golang/go","fork":false,"owner":{"login":"golang"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","utopian-io","fullstack","apps","web"],"moderator":{"account":"yokunjon","time":"2018-04-29T03:44:32.627Z","pending":true,"reviewed":false,"flagged":false},"questions":null,"score":null,"total_influence":null,"staff_pick":null,"staff_pick_by":null,"config":{"questions":[{"question":"How many substantial concepts does this tutorial address?","question_id":"tuts-1","answers":[{"answer":"4-5 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-1","value":10},{"answer":"2-3 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-2","value":7},{"answer":"1 substantial concept covered in the tutorial.","answer_id":"tuts-1-a-3","value":3},{"answer":"More than 5 substantial concepts covered in the tutorial.","answer_id":"tuts-1-a-4","value":0}]},{"question":"Does the title and the outline of the tutorial properly reflect the content?","question_id":"tuts-2","answers":[{"answer":"Yes, it is very clear.","answer_id":"tuts-2-a-1","value":15},{"answer":"To some extent.","answer_id":"tuts-2-a-2","value":11.5},{"answer":"The title is somewhat misleading and/or the outline is not detailed or informative enough.","answer_id":"tuts-2-a-3","value":4.5},{"answer":"Title and outline are of little or no relevance to the content of the tutorial.","answer_id":"tuts-2-a-4","value":0}]},{"question":"Did the contributor provide supplementary resources, such as code and sample files in the contribution post or a linked GitHub repository?","question_id":"tuts-3","answers":[{"answer":"Yes, exceptional supplementary resources are provided including a relevant github repo/gist.","answer_id":"tuts-3-a-1","value":15},{"answer":"Supplementary resources provided are of high relevance.","answer_id":"tuts-3-a-2","value":12},{"answer":"Contributor provides minimal supplementary resources.","answer_id":"tuts-3-a-3","value":6},{"answer":"No supplementary resources were provided.","answer_id":"tuts-3-a-4","value":0}]},{"question":"Is the tutorial part of a series?","question_id":"tuts-4","answers":[{"answer":"Yes.","answer_id":"tuts-4-a-1","value":10},{"answer":"Yes, but it is the first entry in the series.","answer_id":"tuts-4-a-2","value":7},{"answer":"No, but it works just fine as a stand-alone tutorial.","answer_id":"tuts-4-a-3","value":5},{"answer":"No.","answer_id":"tuts-4-a-4","value":0}]},{"question":"Does the tutorial contain sufficient explanatory visuals?","question_id":"tuts-5","answers":[{"answer":"Yes, the visual components of the post were adequate in quality and quantity.","answer_id":"tuts-5-a-1","value":10},{"answer":"The volume of visual components included was unnecessarily large.","answer_id":"tuts-5-a-2","value":7},{"answer":"The post lacked sufficient visualization to easily learn from the content.","answer_id":"tuts-5-a-3","value":3},{"answer":"No visualization was presented in this contribution.","answer_id":"tuts-5-a-4","value":0}]},{"question":"How unique and/or innovative are the concepts covered in the tutorial?","question_id":"tuts-6","answers":[{"answer":"This was the first time I read about the concepts covered.","answer_id":"tuts-6-a-1","value":10},{"answer":"The concepts covered were innovative and offer some usefulness.","answer_id":"tuts-6-a-2","value":7},{"answer":"I have read several similar ideas and thoughts elsewhere, but this one was of higher quality.","answer_id":"tuts-6-a-3","value":5},{"answer":"Such tutorials can be found online with great ease and the contribution add no value to the open source community.","answer_id":"tuts-6-a-4","value":0}]},{"question":"How would you describe the formatting, language and overall presentation of the post?","question_id":"c-1","answers":[{"answer":"The post is of very high quality.","answer_id":"c-1-a-1","value":10},{"answer":"The post is of decent quality, but not spectacular in any way.","answer_id":"c-1-a-2","value":7},{"answer":"The post is poorly written and/or formatted, but readable.","answer_id":"c-1-a-3","value":3},{"answer":"The post is really hard to read and the content is barely understandable.","answer_id":"c-1-a-4","value":0}]},{"question":"How would you rate the overall value of this contribution on the open source community and ecosystem?","question_id":"c-2","answers":[{"answer":"This contribution brings great and impactful value, and can be used for applications outside the specific project.","answer_id":"c-2-a-1","value":20},{"answer":"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.","answer_id":"c-2-a-2","value":16},{"answer":"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.","answer_id":"c-2-a-3","value":8},{"answer":"This contribution adds no value to the open source community and ecosystem or the specific project.","answer_id":"c-2-a-4","value":0}]}]}}
Transaction InfoBlock #21980496/Trx 525f3b3fadaa4ccd4344d89b922058f18ec6512f
View Raw JSON Data
{
  "trx_id": "525f3b3fadaa4ccd4344d89b922058f18ec6512f",
  "block": 21980496,
  "trx_in_block": 11,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-29T03:44:33",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "build-complete-full-stack-web-app-using-go-programming-language",
      "title": "Build Complete Full Stack Web App Using Go Programming Language ",
      "body": "#### Welcome to the First Part of the Tutorial on Build Complete Full Stack Web App Using Go Programming Language \n<center> <img src= https://imgur.com/Rajc7CQ.jpg/> </center>\n\n#### What Will I Learn?\n\n- You will learn how to develop full stack web application using Go\n- You will learn how to create HTTP server and making routes\n- You will learn about static files and their creation\n- Your will learn about the REST API handlers and testing\n\n\n#### Requirements\n##### System Requirements:\n\n- [Go Programming Language]( https://golang.org/dl/) for building App\n- The Basic Command Line\n##### OS Support:\n\n- Windows 7/8/10\n- macOS \n- Linux \n#### Difficulty\n\n\n\n- Intermediate\n\n#### Required Understanding\n- You just need beginner level understanding of the Go programming language.\n- A fair understanding of Programming Languages\n- A thirst for learning and developing something new\n\n\n#### Description\n-\tGo gets increasingly more well-known as the go-to language to develop web based applications.\n-\tAll you need is a little bit of understanding of web design. If you are a web developer and want to build Full Stack Apps, this tutorial is for you.With this particular tutorial, I really hope to get the center ground and provide a single source that explains steps to make a full stack web app in Go, together with adequate test instances.\n#### What is Go Programming Language ?\nGo is an open source programming language which makes it simple to develop easy, dependable, and effective software.\nGo is surely an incredible option for a language as it was developed by a few of the exact same individuals who created the C programming language, Unix, and UTF-8 - probably the most important efforts to computer science. Robert Griesemer, Rob Pike, and Ken Thompson developed Go to become a modern language which easily uses several cores, easily implements concurrency, very easily works in distributed environments, and simply enables the developer to write applications - it has a really lean and user friendly format.\n\n#### What is Full Stack ?\nWe will develop a community encyclopedia of animals. This website will :\n\n-Display the various records submitted through the community, using the name and information on the animal they will located.\n-Permit anyone to post a fresh entry about a animal which they found.\n\nThis application will require three components :\n1.\tThe web server\n2.\tThe front-end app\n3.\tThe database\n### Setting up the environment\nThis section explains how you can set up your own environment and project structure the first time\n\n#### 1. Set up your $GOPATH\nRun this command to check the current value of your `$GOPATH `environment variable :\n`echo $GOPATH`\nIf you do not get a directory name, include the `GOPATH` variable to your environment (you are able to choose any directory location you would like, however it will be much better if you create a brand new directory for this) :\n\n`export GOPATH=\"/location/of/your/gopath/directory\"`\nYou can paste the above line in you `.bashrc `or `.zshrc `file, in case you wish to make the variable to be permanent.\n#### 2. Set up directory structure\nHereafter, the actual **“Go directory”** will certainly make reference to the place described from your `$GOPATH` environment variable. Within the Go directory, you will need to create 3 folders (if they happen to be not there previously) :\n\n```\n# Inside the Go directory\nmkdir src\nmkdir pkg\nmkdir bin\n```\nThe purpose of each directory can be seen from its name:\n• bin - is actually wherever all of the executable binaries produced by compiling your code go\n• pkg - Consists of package objects created by libraries (that you do not have to think about now)\n• src - is actually wherever all of your Go source code will go. Yes, the whole thing. Even which weird side project that you will be thinking of building.\n#### 3. Making your project directory\nThe project folders within the src directory must stick to that exact same location structure since the place wherever your remote repository is situated. So, for instance, if I make a new project known as **“animalpedia”**, and i also make a repository for that below my name on github, in a way that the location of the project repository will be on `github.com/exploringworld/animalpedia`, then the place of this project in the computer could be : \n`$GOPATH/src/github.com/exploringworld/animalpedia`\n\nGo on and create a comparable directory for your project. In case you have not created an online repo yet, simply name the directories based on the location which you intend to put your own code in.\n\nThis particular location on your pc will henceforth become known as your **project directory**\n### Getting HTTP server\n\nWithin your project directory, make a file known as `main.go` inside your project directory :\n\n`touch main.go`\n\nThis particular file will contain the program code to start your server :\n\n```// This is the name of package below\n// Anything within our this package name can see everything\npackage main\n\n// Below are the names of libraries we going to use\n// Both \"fmt\" and \"net\" are part of the Go Language standard library\nimport (\n\t// \"fmt\" has methods for formatted I/O operations\t\"fmt\"\n\t// The \"net/http\" library contains methods to implement HTTP clients and servers\n\t\"net/http\"\n)\n\nfunc main() {\n\t// The \"HandleFunc\" method takes a path and a function as arguments\n\t// (Yes, we can pass functions as arguments, and even treat them like variables in Go Programming language)\n\t// BUT, the handler function has to must have the appropriate signature\n\thttp.HandleFunc(\"/\", handler)\n\n\t// After we define our server, we now \"listen and serve\" on port 8080\n\t// The second argument is the handler, which we will come to later on, but for now it is left as nil,\n\t// and the handler defined above (in \"HandleFunc\") is used\n\thttp.ListenAndServe(\":8080\", nil)\n}\n\n// \"handler\" is our handler function. It has to follow the function signature of a ResponseWriter and Request type\n// as the arguments.\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\t// For this, we would always pipe the \"Hello World\" into the response writer\n\tfmt.Fprintf(w, \"Hello World!\")\n}\n```\n`fmt.Fprintf,` in contrast to another `printf` statements you might know, requires a “writer” as its 1st argument. The 2nd argument will be the data which is piped in to this writer. The outcome therefore seems based on where the writer goes it. In our situation the `ResponseWriter` w writes the output as the response to users request.\n`\n\nYou now run this file :\n`go run main.go`\nAnd navigate to http://localhost:8080 in your browser, or by running the command  through CMD.\n`curl localhost:8080`\nAnd see the code output: **“Hello World!”**\nYou have now successfully started an HTTP server in Go Language.\n### Making the routes\nOur own server is currently operating, but, you may observe that we get exactly the same “Hello World!”response whatever the route we strike, or the HTTP method we utilize. To find out this on your own, run the following curl commands, and take notice of the response that this server will give you :\n```\ncurl localhost:8080/some-other-route\ncurl -X POST localhost:8080\ncurl -X PUT localhost:8080/samething\n```\nAll three commands are still going to give you “Hello World!”\nWe would like to provide our server a bit more intelligence compared to this, to ensure that we are able to manage a number of paths and methods. This is where routing is necessary.\nEven though you are able to accomplish this with Go’s `net/http` standard library, there are many libraries available that offer a more idiomatic as well as declarative method to handle http routing.\n\n### Installing external libraries into Go\nWe are setting up a few external libraries through the following tutorial, in which the standard libraries do not give the features that we desire.\nWhenever we install libraries, we want a way to make sure that others who work with our code also provide exactly the same version of the library that we perform.\nTo do this, we make use of a “package manager” tool. This specific tool acts several purposes:\n•\tIt ensures the versions associated with any external libraries we all install tend to be locked down, to ensure that breaking changes in some of the libraries usually do not affect our program code.\n•\tIt brings the necessary external libraries and stores them locally, in order that various projects may use diverse versions of the same library, when they need to.\n•\tIt stores the names and versions of most our external libraries, so others may set up the same versions which we are working along with on this system.\nThe official package manager for Go (to be more exact “official experiment” which is “safe for production use” as explained on the homepage) is known as dep. You are able to install dep by following the actual setup guide `https://github.com/golang/dep`. You can actually confirm its installation after running :\n\n\n`dep version`\nwhich will output a few information on the particular version when successful.\nIn order to load package management for the project, run the command :\n`dep init`\nThis can produce the` Gopkg.toml` and `Gopkg.lock` files, which are the files which are useful to record and lock dependencies within our project.\nNext, we set up our routing library:\n`dep ensure -add github.com/gorilla/mux`\nThis will add the `gorilla/mux` library to your project.\nRight now, we are able to change the code to work with features this library provides :\n```\npackage main\n\nimport (\n\t// Import the gorilla/mux library we just installed\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/gorilla/mux\"\n)\n\nfunc main() {\n\t// Declare a new router\n\tr := mux.NewRouter()\n\n\t// This is where the router is useful, it allows us to declare methods that\n\t// this path will be valid for\n\tr.HandleFunc(\"/hello\", handler).Methods(\"GET\")\n\n\t// We can then pass our router (after declaring all our routes) to this method\n\t// (where previously, we were leaving the secodn argument as nil)\n\thttp.ListenAndServe(\":8080\", r)\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintf(w, \"Hello World!\")\n}\n```\n### Testing Our Application\nTesting is definitely an important section of building any application **“production quality”**. It makes sure that our app functions like we anticipate that it will.\nLets begin by testing our handler. Create a file named main_test.go:\n```\n//main_test.go\n\npackage main\n\nimport (\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n)\n\nfunc TestHandler(t *testing.T) {\n\t//Here, we form a new HTTP request. This is the request that's going to be\n\t// passed to our handler.\n\t// The first argument is the method, the second argument is the route (which \n\t//we leave blank for now, and will get back to soon), and the third is the \n\t//request body, which we don't have in this case.\n\treq, err := http.NewRequest(\"GET\", \"\", nil)\n\n\t// In case there is an error in forming the request, we fail and stop the test\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We use Go's httptest library to create an http recorder. This recorder\n\t// will act as the target of our http request\n\t// (you can think of it as a mini-browser, which will accept the result of \n\t// the http request that we make)\n\trecorder := httptest.NewRecorder()\n\n\t// Create an HTTP handler from our handler function. \"handler\" is the handler \n\t// function defined in our main.go file that we want to test\n\thf := http.HandlerFunc(handler)\n\n\t// Serve the HTTP request to our recorder. This is the line that actually\n\t// executes our the handler that we want to test\n\thf.ServeHTTP(recorder, req)\n\n\t// Check the status code is what we expect.\n\tif status := recorder.Code; status != http.StatusOK {\n\t\tt.Errorf(\"handler returned wrong status code: got %v want %v\",\n\t\t\tstatus, http.StatusOK)\n\t}\n\n\t// Check the response body is what we expect.\n\texpected := `Hello World!`\n\tactual := recorder.Body.String()\n\tif actual != expected {\n\t\tt.Errorf(\"handler returned unexpected body: got %v want %v\", actual, expected)\n\t}\n}\n```\nGo utilizes a convention that will determines the test file when it has got the pattern `*_test.go`\nTo perform this test, simply run :\ngo test ./...\nfrom the project main directory. You need to see a mild message suggesting that every thing went ok.\n\n### Making our routing to test\nIf you see in our earlier snippet, we kept the **“route”** empty while creating the mock request applying `http.newRequest`. So how exactly does this particular test continue to pass if your handler will be defined just for `“GET /handler”` route?\nWell, ends up this test was just testing our handler and not the actual routing to the handler. In other words, which means that the above mentioned test makes sure that the request arriving will get functioned properly provided that it is sent to the right handler.\nIn this portion, we are going to test this routing, to ensure that we are able to make sure that every handler will be mapped on the correct HTTP route.\nPrior to we continue to test our routing, it is essential to ensure that the code can be analyzed for this. Change the main.go file to appear like this:\n```\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/gorilla/mux\"\n)\n\n// The new router function creates the router and\n// returns it to us. We can now use this function\n// to instantiate and test the router outside of the main function\nfunc newRouter() *mux.Router {\n\tr := mux.NewRouter()\n\tr.HandleFunc(\"/hello\", handler).Methods(\"GET\")\n\treturn r\n}\n\nfunc main() {\n\t// The router is now formed by calling the `newRouter` constructor function\n\t// that we defined above. The rest of the code stays the same\n\tr := newRouter()\n\thttp.ListenAndServe(\":8080\", r)\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintf(w, \"Hello World!\")\n}\n```\nNow  our route constructor function is separated, let us see test our routing:\n```\nfunc TestRouter(t *testing.T) {\n\t// Instantiate the router using the constructor function that\n\t// we defined previously\n\tr := newRouter()\n\n\t// Create a new server using the \"httptest\" libraries `NewServer` method\n\t// Documentation : https://golang.org/pkg/net/http/httptest/#NewServer\n\tmockServer := httptest.NewServer(r)\n\n\t// The mock server we created runs a server and exposes its location in the\n\t// URL attribute\n\t// We make a GET request to the \"hello\" route we defined in the router\n\tresp, err := http.Get(mockServer.URL + \"/hello\")\n\n\t// Handle any unexpected error\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We want our status to be 200 (ok)\n\tif resp.StatusCode != http.StatusOK {\n\t\tt.Errorf(\"Status should be ok, got %d\", resp.StatusCode)\n\t}\n\n\t// In the next few lines, the response body is read, and converted to a string\n\tdefer resp.Body.Close()\n\t// read the body into a bunch of bytes (b)\n\tb, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\t// convert the bytes to a string\n\trespString := string(b)\n\texpected := \"Hello World!\"\n\n\t// We want our response to match the one defined in our handler.\n\t// If it does happen to be \"Hello world!\", then it confirms, that the\n\t// route is correct\n\tif respString != expected {\n\t\tt.Errorf(\"Response should be %s, got %s\", expected, respString)\n\t}\n\n}\n```\nNow we all know that each time we hit the actual `GET /hello route`, we have a response of hello world. When we hit some other route, it should respond having a 404. Actually, let us write a test for exactly this condition :\n```\nfunc TestRouterForNonExistentRoute(t *testing.T) {\n\tr := newRouter()\n\tmockServer := httptest.NewServer(r)\n\t// Most of the code is similar. The only difference is that now we make a \n\t//request to a route we know we didn't define, like the `POST /hello` route.\n\tresp, err := http.Post(mockServer.URL+\"/hello\", \"\", nil)\n\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We want our status to be 405 (method not allowed)\n\tif resp.StatusCode != http.StatusMethodNotAllowed {\n\t\tt.Errorf(\"Status should be 405, got %d\", resp.StatusCode)\n\t}\n\n\t// The code to test the body is also mostly the same, except this time, we \n\t// expect an empty body\n\tdefer resp.Body.Close()\n\tb, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\trespString := string(b)\n\texpected := \"\"\n\n\tif respString != expected {\n\t\tt.Errorf(\"Response should be %s, got %s\", expected, respString)\n\t}\n\n}\n```\nSince we have figured out how you can make a simple http server, we are able to serve static files from this for the users to interact with.\n### Serving the Assets files\n**“Static files”** are the HTML, CSS, JavaScript, images, and also the additional static asset files which are required to form a web site.\nYou will find 3 actions we must take in so that it will create our server.Now serve these types oo static assets.\n1.\tMake static assets\n2.\tChange our router in order to assist static assets\n3.\tInclude tests to confirm our new server can easily serve static files\n#### Create static assets\nTo create static assets, make a directory in your project root directory, and name it `assets` :\n`mkdir assets`\nFollowing, create an HTML file within this directory. This is actually the file we will serve, together with any file which goes in the assets directory :\n`touch assets/index.html`\n#### Modify the router\nInterestingly sufficient, the whole file server could be enabled in only adding Three lines of code within the router. The newest router constructor may be like this :\n```\nfunc newRouter() *mux.Router {\n\tr := mux.NewRouter()\n\tr.HandleFunc(\"/hello\", handler).Methods(\"GET\")\n\n\t// Declare the static file directory and point it to the \n\t// directory we just made\n\tstaticFileDirectory := http.Dir(\"./assets/\")\n\t// Declare the handler, that routes requests to their respective filename.\n\t// The fileserver is wrapped in the `stripPrefix` method, because we want to\n\t// remove the \"/assets/\" prefix when looking for files.\n\t// For example, if we type \"/assets/index.html\" in our browser, the file server\n\t// will look for only \"index.html\" inside the directory declared above.\n\t// If we did not strip the prefix, the file server would look for \n\t// \"./assets/assets/index.html\", and yield an error\n\tstaticFileHandler := http.StripPrefix(\"/assets/\", http.FileServer(staticFileDirectory))\n\t// The \"PathPrefix\" method acts as a matcher, and matches all routes starting\n\t// with \"/assets/\", instead of the absolute route itself\n\tr.PathPrefix(\"/assets/\").Handler(staticFileHandler).Methods(\"GET\")\n\treturn r\n}\n```\n#### Testing of static file server\nIt's hard to really say that you will have finished a feature unless you possess tests for it. We can easily check the static file server by having another test function to main_test.go :\n```\nfunc TestStaticFileServer(t *testing.T) {\n\tr := newRouter()\n\tmockServer := httptest.NewServer(r)\n\n\t// We want to hit the `GET /assets/` route to get the index.html file response\n\tresp, err := http.Get(mockServer.URL + \"/assets/\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We want our status to be 200 (ok)\n\tif resp.StatusCode != http.StatusOK {\n\t\tt.Errorf(\"Status should be 200, got %d\", resp.StatusCode)\n\t}\n\n\t// It isn't wise to test the entire content of the HTML file.\n\t// Instead, we test that the content-type header is \"text/html; charset=utf-8\"\n\t// so that we know that an html file has been served\n\tcontentType := resp.Header.Get(\"Content-Type\")\n\texpectedContentType := \"text/html; charset=utf-8\"\n\n\tif expectedContentType != contentType {\n\t\tt.Errorf(\"Wrong content type, expected %s, got %s\", expectedContentType, contentType)\n\t}\n\n}\n```\nTo actually test your work, run the server :\n`go run main.go`\nthen, navigate to http://localhost:8080/assets/ in your web browser.\n#### Making of web browser application\nBecause we have to make our animal encyclopedia, lets make a simple HTML file which shows record of animals, as well as brings the list from an API on-page load, plus offers a form to up-date checklist of animals:\n```\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <title>The animal encyclopedia</title>\n</head>\n\n<body>\n  <h1>The animal encyclopedia</h1>\n  <!-- \n    This section of the document specifies the table that will\n    be used to display the list of animals and their description\n   -->\n  <table>\n    <tr>\n      <th>Species</th>\n      <th>Description</th>\n    </tr>\n    <td>Lion</td>\n    <td>Common between cities</td>\n    </tr>\n  </table>\n  <br/>\n\n  <!-- \n    This section contains the form, that will be used to hit the \n    `POST /animal` API that we will build in the next section\n   -->\n  <form action=\"/animal\" method=\"post\">\n    Species:\n    <input type=\"text\" name=\"species\">\n    <br/> Description:\n    <input type=\"text\" name=\"description\">\n    <br/>\n    <input type=\"submit\" value=\"Submit\">\n  </form>\n\n  <!-- \n    Finally, the last section is the script that will\n    run on each page load to fetch the list of animals\n    and add them to our existing table\n   -->\n  <script>\n    animalTable = document.querySelector(\"table\")\n\n    /*\n    Use the browsers `fetch` API to make a GET call to /animal\n    We expect the response to be a JSON list of animals, of the\n    form :\n    [\n      {\"species\":\"...\",\"description\":\"...\"},\n      {\"species\":\"...\",\"description\":\"...\"}\n    ]\n    */\n    fetch(\"/animal\")\n      .then(response => response.json())\n      .then(animalList => {\n        //Once we fetch the list, we iterate over it\n        animalList.forEach(animal => {\n          // Create the table row\n          row = document.createElement(\"tr\")\n\n          // Create the table data elements for the species and\n\t\t\t\t\t// description columns\n          species = document.createElement(\"td\")\n          species.innerHTML = animal.species\n          description = document.createElement(\"td\")\n          description.innerHTML = animal.description\n\n          // Add the data elements to the row\n          row.appendChild(species)\n          row.appendChild(description)\n          // Finally, add the row element to the table itself\n          animalTable.appendChild(row)\n        })\n      })\n  </script>\n</body>\n```\n### Addition of animal REST API handlers\nWe are able to see, we will have to apply 2 APIs to ensure that this app to function:\n1. GET /animal - which will retrieve record of all animals presently within the system\n2. POST /animal - which will create an entrance to the current set of animals\nIn this, we are going to write the related handlers.\nCreate a new file named animal_handlers.go, next to the main.go file.\nInitially, we are going to include the definition of the Animal struct as well as initialize a common animal variable:\n```\ntype Animal struct {\n\tSpecies     string `json:\"species\"`\n\tDescription string `json:\"description\"`\n}\n\nvar animals []Animal\n```\nNext, define the handler to get all animals :\n```\nfunc getAnimalHandler(w http.ResponseWriter, r *http.Request) {\n\t//Convert the \"animals\" variable to json\n\tanimalListBytes, err := json.Marshal(animals)\n\n\t// If there is an error, print it to the console, and return a server\n\t// error response to the user\n\tif err != nil {\n\t\tfmt.Println(fmt.Errorf(\"Error: %v\", err))\n\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\treturn\n\t}\n\t// If all goes well, write the JSON list of animals to the response\n\tw.Write(animalListBytes)\n}\n```\nNext, the handler to create a new entry of animals :\n```\nfunc createAnimalHandler(w http.ResponseWriter, r *http.Request) {\n\t// Create a new instance of Animal\n\tanimal := Animal{}\n\n\t// We send all our data as HTML form data\n\t// the `ParseForm` method of the request, parses the\n\t// form values\n\terr := r.ParseForm()\n\n\t// In case of any error, we respond with an error to the user\n\tif err != nil {\n\t\tfmt.Println(fmt.Errorf(\"Error: %v\", err))\n\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\t// Get the information about the animal from the form info\n\tanimal.Species = r.Form.Get(\"species\")\n\tanimal.Description = r.Form.Get(\"description\")\n\n\t// Append our existing list of animals with a new entry\n\tanimals = append(animals, animal)\n\n\t//Finally, we redirect the user to the original HTMl page\n\t// (located at `/assets/`), using the http libraries `Redirect` method\n\thttp.Redirect(w, r, \"/assets/\", http.StatusFound)\n}\n```\nThe final stage, is to include these handler to our router, to be able to allow them to use by the app :\n```\n\t// These lines are added inside the newRouter() function before returning r\n\tr.HandleFunc(\"/animal\", getAnimalHandler).Methods(\"GET\")\n\tr.HandleFunc(\"/animal\", createAnimalHandler).Methods(\"POST\")\n\treturn r\n```\nThe tests regarding the two handlers and also the routing included are similar to the last tests we had written for the GET /hello handler and static file server, and they are still left as an exercise for the readers.\n\n### Summary\nUp to now, we now have included persistence to the application, using the information about various animals getting saved and retrieved.\nNevertheless, that persistence is temporary, because it is in memory space. Which means that at any time you reboot your application, all of the information will get removed. To be able to bring correct persistence, we are going to must add a database to the stack.\nSo far, the code had been simple to reason about and test, as it was obviously a standalone application. Including a database will certainly add an additional layer of communication.\nWe will be going to create a database and connected to our application in the next part of the tutorial\n\n\n<br /><hr/><em>Posted on <a href=\"https://utopian.io/utopian-io/@exploringworld/build-complete-full-stack-web-app-using-go-programming-language\">Utopian.io -  Rewarding Open Source Contributors</a></em><hr/>",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":23096959,\"name\":\"go\",\"full_name\":\"golang/go\",\"html_url\":\"https://github.com/golang/go\",\"fork\":false,\"owner\":{\"login\":\"golang\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"utopian-io\",\"fullstack\",\"apps\",\"web\"],\"moderator\":{\"account\":\"yokunjon\",\"time\":\"2018-04-29T03:44:32.627Z\",\"pending\":true,\"reviewed\":false,\"flagged\":false},\"questions\":null,\"score\":null,\"total_influence\":null,\"staff_pick\":null,\"staff_pick_by\":null,\"config\":{\"questions\":[{\"question\":\"How many substantial concepts does this tutorial address?\",\"question_id\":\"tuts-1\",\"answers\":[{\"answer\":\"4-5 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-1\",\"value\":10},{\"answer\":\"2-3 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-2\",\"value\":7},{\"answer\":\"1 substantial concept covered in the tutorial.\",\"answer_id\":\"tuts-1-a-3\",\"value\":3},{\"answer\":\"More than 5 substantial concepts covered in the tutorial.\",\"answer_id\":\"tuts-1-a-4\",\"value\":0}]},{\"question\":\"Does the title and the outline of the tutorial properly reflect the content?\",\"question_id\":\"tuts-2\",\"answers\":[{\"answer\":\"Yes, it is very clear.\",\"answer_id\":\"tuts-2-a-1\",\"value\":15},{\"answer\":\"To some extent.\",\"answer_id\":\"tuts-2-a-2\",\"value\":11.5},{\"answer\":\"The title is somewhat misleading and/or the outline is not detailed or informative enough.\",\"answer_id\":\"tuts-2-a-3\",\"value\":4.5},{\"answer\":\"Title and outline are of little or no relevance to the content of the tutorial.\",\"answer_id\":\"tuts-2-a-4\",\"value\":0}]},{\"question\":\"Did the contributor provide supplementary resources, such as code and sample files in the contribution post or a linked GitHub repository?\",\"question_id\":\"tuts-3\",\"answers\":[{\"answer\":\"Yes, exceptional supplementary resources are provided including a relevant github repo/gist.\",\"answer_id\":\"tuts-3-a-1\",\"value\":15},{\"answer\":\"Supplementary resources provided are of high relevance.\",\"answer_id\":\"tuts-3-a-2\",\"value\":12},{\"answer\":\"Contributor provides minimal supplementary resources.\",\"answer_id\":\"tuts-3-a-3\",\"value\":6},{\"answer\":\"No supplementary resources were provided.\",\"answer_id\":\"tuts-3-a-4\",\"value\":0}]},{\"question\":\"Is the tutorial part of a series?\",\"question_id\":\"tuts-4\",\"answers\":[{\"answer\":\"Yes.\",\"answer_id\":\"tuts-4-a-1\",\"value\":10},{\"answer\":\"Yes, but it is the first entry in the series.\",\"answer_id\":\"tuts-4-a-2\",\"value\":7},{\"answer\":\"No, but it works just fine as a stand-alone tutorial.\",\"answer_id\":\"tuts-4-a-3\",\"value\":5},{\"answer\":\"No.\",\"answer_id\":\"tuts-4-a-4\",\"value\":0}]},{\"question\":\"Does the tutorial contain sufficient explanatory visuals?\",\"question_id\":\"tuts-5\",\"answers\":[{\"answer\":\"Yes, the visual components of the post were adequate in quality and quantity.\",\"answer_id\":\"tuts-5-a-1\",\"value\":10},{\"answer\":\"The volume of visual components included was unnecessarily large.\",\"answer_id\":\"tuts-5-a-2\",\"value\":7},{\"answer\":\"The post lacked sufficient visualization to easily learn from the content.\",\"answer_id\":\"tuts-5-a-3\",\"value\":3},{\"answer\":\"No visualization was presented in this contribution.\",\"answer_id\":\"tuts-5-a-4\",\"value\":0}]},{\"question\":\"How unique and/or innovative are the concepts covered in the tutorial?\",\"question_id\":\"tuts-6\",\"answers\":[{\"answer\":\"This was the first time I read about the concepts covered.\",\"answer_id\":\"tuts-6-a-1\",\"value\":10},{\"answer\":\"The concepts covered were innovative and offer some usefulness.\",\"answer_id\":\"tuts-6-a-2\",\"value\":7},{\"answer\":\"I have read several similar ideas and thoughts elsewhere, but this one was of higher quality.\",\"answer_id\":\"tuts-6-a-3\",\"value\":5},{\"answer\":\"Such tutorials can be found online with great ease and the contribution add no value to the open source community.\",\"answer_id\":\"tuts-6-a-4\",\"value\":0}]},{\"question\":\"How would you describe the formatting, language and overall presentation of the post?\",\"question_id\":\"c-1\",\"answers\":[{\"answer\":\"The post is of very high quality.\",\"answer_id\":\"c-1-a-1\",\"value\":10},{\"answer\":\"The post is of decent quality, but not spectacular in any way.\",\"answer_id\":\"c-1-a-2\",\"value\":7},{\"answer\":\"The post is poorly written and/or formatted, but readable.\",\"answer_id\":\"c-1-a-3\",\"value\":3},{\"answer\":\"The post is really hard to read and the content is barely understandable.\",\"answer_id\":\"c-1-a-4\",\"value\":0}]},{\"question\":\"How would you rate the overall value of this contribution on the open source community and ecosystem?\",\"question_id\":\"c-2\",\"answers\":[{\"answer\":\"This contribution brings great and impactful value, and can be used for applications outside the specific project.\",\"answer_id\":\"c-2-a-1\",\"value\":20},{\"answer\":\"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.\",\"answer_id\":\"c-2-a-2\",\"value\":16},{\"answer\":\"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.\",\"answer_id\":\"c-2-a-3\",\"value\":8},{\"answer\":\"This contribution adds no value to the open source community and ecosystem or the specific project.\",\"answer_id\":\"c-2-a-4\",\"value\":0}]}]}}"
    }
  ]
}
2018/04/29 01:05:54
voterst3llar
authorexploringworld
permlinkbuild-complete-full-stack-web-app-using-go-programming-language
weight300 (3.00%)
Transaction InfoBlock #21977323/Trx 5d49688781dc0c8e18ccefb5d079b4bdbd5c410c
View Raw JSON Data
{
  "trx_id": "5d49688781dc0c8e18ccefb5d079b4bdbd5c410c",
  "block": 21977323,
  "trx_in_block": 25,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-29T01:05:54",
  "op": [
    "vote",
    {
      "voter": "st3llar",
      "author": "exploringworld",
      "permlink": "build-complete-full-stack-web-app-using-go-programming-language",
      "weight": 300
    }
  ]
}
2018/04/29 00:54:27
votersensation
authorexploringworld
permlinkbuild-complete-full-stack-web-app-using-go-programming-language
weight10000 (100.00%)
Transaction InfoBlock #21977094/Trx d9e569c8be1c3e5e0215c9de1779667a3a03ff25
View Raw JSON Data
{
  "trx_id": "d9e569c8be1c3e5e0215c9de1779667a3a03ff25",
  "block": 21977094,
  "trx_in_block": 47,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-29T00:54:27",
  "op": [
    "vote",
    {
      "voter": "sensation",
      "author": "exploringworld",
      "permlink": "build-complete-full-stack-web-app-using-go-programming-language",
      "weight": 10000
    }
  ]
}
2018/04/29 00:39:15
voteryuxi
authorexploringworld
permlinkbuild-complete-full-stack-web-app-using-go-programming-language
weight2000 (20.00%)
Transaction InfoBlock #21976790/Trx 12132348bcc1e94d5b7b25ebbb2620abb6df8d65
View Raw JSON Data
{
  "trx_id": "12132348bcc1e94d5b7b25ebbb2620abb6df8d65",
  "block": 21976790,
  "trx_in_block": 11,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-29T00:39:15",
  "op": [
    "vote",
    {
      "voter": "yuxi",
      "author": "exploringworld",
      "permlink": "build-complete-full-stack-web-app-using-go-programming-language",
      "weight": 2000
    }
  ]
}
2018/04/29 00:21:06
authorexploringworld
permlinkbuild-complete-full-stack-web-app-using-go-programming-language
max accepted payout1000000.000 SBD
percent steem dollars10000
allow votestrue
allow curation rewardstrue
extensions[[0,{"beneficiaries":[{"account":"utopian.pay","weight":1500}]}]]
Transaction InfoBlock #21976428/Trx abec30cf9980a203ca016036ddfae2f75a5edccb
View Raw JSON Data
{
  "trx_id": "abec30cf9980a203ca016036ddfae2f75a5edccb",
  "block": 21976428,
  "trx_in_block": 66,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-29T00:21:06",
  "op": [
    "comment_options",
    {
      "author": "exploringworld",
      "permlink": "build-complete-full-stack-web-app-using-go-programming-language",
      "max_accepted_payout": "1000000.000 SBD",
      "percent_steem_dollars": 10000,
      "allow_votes": true,
      "allow_curation_rewards": true,
      "extensions": [
        [
          0,
          {
            "beneficiaries": [
              {
                "account": "utopian.pay",
                "weight": 1500
              }
            ]
          }
        ]
      ]
    }
  ]
}
2018/04/29 00:21:06
parent author
parent permlinkutopian-io
authorexploringworld
permlinkbuild-complete-full-stack-web-app-using-go-programming-language
titleBuild Complete Full Stack Web App Using Go Programming Language
body#### Welcome to the First Part of the Tutorial on Build Complete Full Stack Web App Using Go Programming Language <center> <img src= https://imgur.com/Rajc7CQ.jpg/> </center> #### What Will I Learn? - You will learn how to develop full stack web application using Go - You will learn how to create HTTP server and making routes - You will learn about static files and their creation - Your will learn about the REST API handlers and testing #### Requirements ##### System Requirements: - [Go Programming Language]( https://golang.org/dl/) for building App - The Basic Command Line ##### OS Support: - Windows 7/8/10 - macOS - Linux #### Difficulty - Intermediate #### Required Understanding - You just need beginner level understanding of the Go programming language. - A fair understanding of Programming Languages - A thirst for learning and developing something new #### Description - Go gets increasingly more well-known as the go-to language to develop web based applications. - All you need is a little bit of understanding of web design. If you are a web developer and want to build Full Stack Apps, this tutorial is for you.With this particular tutorial, I really hope to get the center ground and provide a single source that explains steps to make a full stack web app in Go, together with adequate test instances. #### What is Go Programming Language ? Go is an open source programming language which makes it simple to develop easy, dependable, and effective software. Go is surely an incredible option for a language as it was developed by a few of the exact same individuals who created the C programming language, Unix, and UTF-8 - probably the most important efforts to computer science. Robert Griesemer, Rob Pike, and Ken Thompson developed Go to become a modern language which easily uses several cores, easily implements concurrency, very easily works in distributed environments, and simply enables the developer to write applications - it has a really lean and user friendly format. #### What is Full Stack ? We will develop a community encyclopedia of animals. This website will : -Display the various records submitted through the community, using the name and information on the animal they will located. -Permit anyone to post a fresh entry about a animal which they found. This application will require three components : 1. The web server 2. The front-end app 3. The database ### Setting up the environment This section explains how you can set up your own environment and project structure the first time #### 1. Set up your $GOPATH Run this command to check the current value of your `$GOPATH `environment variable : `echo $GOPATH` If you do not get a directory name, include the `GOPATH` variable to your environment (you are able to choose any directory location you would like, however it will be much better if you create a brand new directory for this) : `export GOPATH="/location/of/your/gopath/directory"` You can paste the above line in you `.bashrc `or `.zshrc `file, in case you wish to make the variable to be permanent. #### 2. Set up directory structure Hereafter, the actual **“Go directory”** will certainly make reference to the place described from your `$GOPATH` environment variable. Within the Go directory, you will need to create 3 folders (if they happen to be not there previously) : ``` # Inside the Go directory mkdir src mkdir pkg mkdir bin ``` The purpose of each directory can be seen from its name: • bin - is actually wherever all of the executable binaries produced by compiling your code go • pkg - Consists of package objects created by libraries (that you do not have to think about now) • src - is actually wherever all of your Go source code will go. Yes, the whole thing. Even which weird side project that you will be thinking of building. #### 3. Making your project directory The project folders within the src directory must stick to that exact same location structure since the place wherever your remote repository is situated. So, for instance, if I make a new project known as **“animalpedia”**, and i also make a repository for that below my name on github, in a way that the location of the project repository will be on `github.com/exploringworld/animalpedia`, then the place of this project in the computer could be : `$GOPATH/src/github.com/exploringworld/animalpedia` Go on and create a comparable directory for your project. In case you have not created an online repo yet, simply name the directories based on the location which you intend to put your own code in. This particular location on your pc will henceforth become known as your **project directory** ### Getting HTTP server Within your project directory, make a file known as `main.go` inside your project directory : `touch main.go` This particular file will contain the program code to start your server : ```// This is the name of package below // Anything within our this package name can see everything package main // Below are the names of libraries we going to use // Both "fmt" and "net" are part of the Go Language standard library import ( // "fmt" has methods for formatted I/O operations "fmt" // The "net/http" library contains methods to implement HTTP clients and servers "net/http" ) func main() { // The "HandleFunc" method takes a path and a function as arguments // (Yes, we can pass functions as arguments, and even treat them like variables in Go Programming language) // BUT, the handler function has to must have the appropriate signature http.HandleFunc("/", handler) // After we define our server, we now "listen and serve" on port 8080 // The second argument is the handler, which we will come to later on, but for now it is left as nil, // and the handler defined above (in "HandleFunc") is used http.ListenAndServe(":8080", nil) } // "handler" is our handler function. It has to follow the function signature of a ResponseWriter and Request type // as the arguments. func handler(w http.ResponseWriter, r *http.Request) { // For this, we would always pipe the "Hello World" into the response writer fmt.Fprintf(w, "Hello World!") } ``` `fmt.Fprintf,` in contrast to another `printf` statements you might know, requires a “writer” as its 1st argument. The 2nd argument will be the data which is piped in to this writer. The outcome therefore seems based on where the writer goes it. In our situation the `ResponseWriter` w writes the output as the response to users request. ` You now run this file : `go run main.go` And navigate to http://localhost:8080 in your browser, or by running the command through CMD. `curl localhost:8080` And see the code output: **“Hello World!”** You have now successfully started an HTTP server in Go Language. ### Making the routes Our own server is currently operating, but, you may observe that we get exactly the same “Hello World!”response whatever the route we strike, or the HTTP method we utilize. To find out this on your own, run the following curl commands, and take notice of the response that this server will give you : ``` curl localhost:8080/some-other-route curl -X POST localhost:8080 curl -X PUT localhost:8080/samething ``` All three commands are still going to give you “Hello World!” We would like to provide our server a bit more intelligence compared to this, to ensure that we are able to manage a number of paths and methods. This is where routing is necessary. Even though you are able to accomplish this with Go’s `net/http` standard library, there are many libraries available that offer a more idiomatic as well as declarative method to handle http routing. ### Installing external libraries into Go We are setting up a few external libraries through the following tutorial, in which the standard libraries do not give the features that we desire. Whenever we install libraries, we want a way to make sure that others who work with our code also provide exactly the same version of the library that we perform. To do this, we make use of a “package manager” tool. This specific tool acts several purposes: • It ensures the versions associated with any external libraries we all install tend to be locked down, to ensure that breaking changes in some of the libraries usually do not affect our program code. • It brings the necessary external libraries and stores them locally, in order that various projects may use diverse versions of the same library, when they need to. • It stores the names and versions of most our external libraries, so others may set up the same versions which we are working along with on this system. The official package manager for Go (to be more exact “official experiment” which is “safe for production use” as explained on the homepage) is known as dep. You are able to install dep by following the actual setup guide `https://github.com/golang/dep`. You can actually confirm its installation after running : `dep version` which will output a few information on the particular version when successful. In order to load package management for the project, run the command : `dep init` This can produce the` Gopkg.toml` and `Gopkg.lock` files, which are the files which are useful to record and lock dependencies within our project. Next, we set up our routing library: `dep ensure -add github.com/gorilla/mux` This will add the `gorilla/mux` library to your project. Right now, we are able to change the code to work with features this library provides : ``` package main import ( // Import the gorilla/mux library we just installed "fmt" "net/http" "github.com/gorilla/mux" ) func main() { // Declare a new router r := mux.NewRouter() // This is where the router is useful, it allows us to declare methods that // this path will be valid for r.HandleFunc("/hello", handler).Methods("GET") // We can then pass our router (after declaring all our routes) to this method // (where previously, we were leaving the secodn argument as nil) http.ListenAndServe(":8080", r) } func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") } ``` ### Testing Our Application Testing is definitely an important section of building any application **“production quality”**. It makes sure that our app functions like we anticipate that it will. Lets begin by testing our handler. Create a file named main_test.go: ``` //main_test.go package main import ( "net/http" "net/http/httptest" "testing" ) func TestHandler(t *testing.T) { //Here, we form a new HTTP request. This is the request that's going to be // passed to our handler. // The first argument is the method, the second argument is the route (which //we leave blank for now, and will get back to soon), and the third is the //request body, which we don't have in this case. req, err := http.NewRequest("GET", "", nil) // In case there is an error in forming the request, we fail and stop the test if err != nil { t.Fatal(err) } // We use Go's httptest library to create an http recorder. This recorder // will act as the target of our http request // (you can think of it as a mini-browser, which will accept the result of // the http request that we make) recorder := httptest.NewRecorder() // Create an HTTP handler from our handler function. "handler" is the handler // function defined in our main.go file that we want to test hf := http.HandlerFunc(handler) // Serve the HTTP request to our recorder. This is the line that actually // executes our the handler that we want to test hf.ServeHTTP(recorder, req) // Check the status code is what we expect. if status := recorder.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) } // Check the response body is what we expect. expected := `Hello World!` actual := recorder.Body.String() if actual != expected { t.Errorf("handler returned unexpected body: got %v want %v", actual, expected) } } ``` Go utilizes a convention that will determines the test file when it has got the pattern `*_test.go` To perform this test, simply run : go test ./... from the project main directory. You need to see a mild message suggesting that every thing went ok. ### Making our routing to test If you see in our earlier snippet, we kept the **“route”** empty while creating the mock request applying `http.newRequest`. So how exactly does this particular test continue to pass if your handler will be defined just for `“GET /handler”` route? Well, ends up this test was just testing our handler and not the actual routing to the handler. In other words, which means that the above mentioned test makes sure that the request arriving will get functioned properly provided that it is sent to the right handler. In this portion, we are going to test this routing, to ensure that we are able to make sure that every handler will be mapped on the correct HTTP route. Prior to we continue to test our routing, it is essential to ensure that the code can be analyzed for this. Change the main.go file to appear like this: ``` package main import ( "fmt" "net/http" "github.com/gorilla/mux" ) // The new router function creates the router and // returns it to us. We can now use this function // to instantiate and test the router outside of the main function func newRouter() *mux.Router { r := mux.NewRouter() r.HandleFunc("/hello", handler).Methods("GET") return r } func main() { // The router is now formed by calling the `newRouter` constructor function // that we defined above. The rest of the code stays the same r := newRouter() http.ListenAndServe(":8080", r) } func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") } ``` Now our route constructor function is separated, let us see test our routing: ``` func TestRouter(t *testing.T) { // Instantiate the router using the constructor function that // we defined previously r := newRouter() // Create a new server using the "httptest" libraries `NewServer` method // Documentation : https://golang.org/pkg/net/http/httptest/#NewServer mockServer := httptest.NewServer(r) // The mock server we created runs a server and exposes its location in the // URL attribute // We make a GET request to the "hello" route we defined in the router resp, err := http.Get(mockServer.URL + "/hello") // Handle any unexpected error if err != nil { t.Fatal(err) } // We want our status to be 200 (ok) if resp.StatusCode != http.StatusOK { t.Errorf("Status should be ok, got %d", resp.StatusCode) } // In the next few lines, the response body is read, and converted to a string defer resp.Body.Close() // read the body into a bunch of bytes (b) b, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } // convert the bytes to a string respString := string(b) expected := "Hello World!" // We want our response to match the one defined in our handler. // If it does happen to be "Hello world!", then it confirms, that the // route is correct if respString != expected { t.Errorf("Response should be %s, got %s", expected, respString) } } ``` Now we all know that each time we hit the actual `GET /hello route`, we have a response of hello world. When we hit some other route, it should respond having a 404. Actually, let us write a test for exactly this condition : ``` func TestRouterForNonExistentRoute(t *testing.T) { r := newRouter() mockServer := httptest.NewServer(r) // Most of the code is similar. The only difference is that now we make a //request to a route we know we didn't define, like the `POST /hello` route. resp, err := http.Post(mockServer.URL+"/hello", "", nil) if err != nil { t.Fatal(err) } // We want our status to be 405 (method not allowed) if resp.StatusCode != http.StatusMethodNotAllowed { t.Errorf("Status should be 405, got %d", resp.StatusCode) } // The code to test the body is also mostly the same, except this time, we // expect an empty body defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } respString := string(b) expected := "" if respString != expected { t.Errorf("Response should be %s, got %s", expected, respString) } } ``` Since we have figured out how you can make a simple http server, we are able to serve static files from this for the users to interact with. ### Serving the Assets files **“Static files”** are the HTML, CSS, JavaScript, images, and also the additional static asset files which are required to form a web site. You will find 3 actions we must take in so that it will create our server.Now serve these types oo static assets. 1. Make static assets 2. Change our router in order to assist static assets 3. Include tests to confirm our new server can easily serve static files #### Create static assets To create static assets, make a directory in your project root directory, and name it `assets` : `mkdir assets` Following, create an HTML file within this directory. This is actually the file we will serve, together with any file which goes in the assets directory : `touch assets/index.html` #### Modify the router Interestingly sufficient, the whole file server could be enabled in only adding Three lines of code within the router. The newest router constructor may be like this : ``` func newRouter() *mux.Router { r := mux.NewRouter() r.HandleFunc("/hello", handler).Methods("GET") // Declare the static file directory and point it to the // directory we just made staticFileDirectory := http.Dir("./assets/") // Declare the handler, that routes requests to their respective filename. // The fileserver is wrapped in the `stripPrefix` method, because we want to // remove the "/assets/" prefix when looking for files. // For example, if we type "/assets/index.html" in our browser, the file server // will look for only "index.html" inside the directory declared above. // If we did not strip the prefix, the file server would look for // "./assets/assets/index.html", and yield an error staticFileHandler := http.StripPrefix("/assets/", http.FileServer(staticFileDirectory)) // The "PathPrefix" method acts as a matcher, and matches all routes starting // with "/assets/", instead of the absolute route itself r.PathPrefix("/assets/").Handler(staticFileHandler).Methods("GET") return r } ``` #### Testing of static file server It's hard to really say that you will have finished a feature unless you possess tests for it. We can easily check the static file server by having another test function to main_test.go : ``` func TestStaticFileServer(t *testing.T) { r := newRouter() mockServer := httptest.NewServer(r) // We want to hit the `GET /assets/` route to get the index.html file response resp, err := http.Get(mockServer.URL + "/assets/") if err != nil { t.Fatal(err) } // We want our status to be 200 (ok) if resp.StatusCode != http.StatusOK { t.Errorf("Status should be 200, got %d", resp.StatusCode) } // It isn't wise to test the entire content of the HTML file. // Instead, we test that the content-type header is "text/html; charset=utf-8" // so that we know that an html file has been served contentType := resp.Header.Get("Content-Type") expectedContentType := "text/html; charset=utf-8" if expectedContentType != contentType { t.Errorf("Wrong content type, expected %s, got %s", expectedContentType, contentType) } } ``` To actually test your work, run the server : `go run main.go` then, navigate to http://localhost:8080/assets/ in your web browser. #### Making of web browser application Because we have to make our animal encyclopedia, lets make a simple HTML file which shows record of animals, as well as brings the list from an API on-page load, plus offers a form to up-date checklist of animals: ``` <!DOCTYPE html> <html lang="en"> <head> <title>The animal encyclopedia</title> </head> <body> <h1>The animal encyclopedia</h1> <!-- This section of the document specifies the table that will be used to display the list of animals and their description --> <table> <tr> <th>Species</th> <th>Description</th> </tr> <td>Lion</td> <td>Common between cities</td> </tr> </table> <br/> <!-- This section contains the form, that will be used to hit the `POST /animal` API that we will build in the next section --> <form action="/animal" method="post"> Species: <input type="text" name="species"> <br/> Description: <input type="text" name="description"> <br/> <input type="submit" value="Submit"> </form> <!-- Finally, the last section is the script that will run on each page load to fetch the list of animals and add them to our existing table --> <script> animalTable = document.querySelector("table") /* Use the browsers `fetch` API to make a GET call to /animal We expect the response to be a JSON list of animals, of the form : [ {"species":"...","description":"..."}, {"species":"...","description":"..."} ] */ fetch("/animal") .then(response => response.json()) .then(animalList => { //Once we fetch the list, we iterate over it animalList.forEach(animal => { // Create the table row row = document.createElement("tr") // Create the table data elements for the species and // description columns species = document.createElement("td") species.innerHTML = animal.species description = document.createElement("td") description.innerHTML = animal.description // Add the data elements to the row row.appendChild(species) row.appendChild(description) // Finally, add the row element to the table itself animalTable.appendChild(row) }) }) </script> </body> ``` ### Addition of animal REST API handlers We are able to see, we will have to apply 2 APIs to ensure that this app to function: 1. GET /animal - which will retrieve record of all animals presently within the system 2. POST /animal - which will create an entrance to the current set of animals In this, we are going to write the related handlers. Create a new file named animal_handlers.go, next to the main.go file. Initially, we are going to include the definition of the Animal struct as well as initialize a common animal variable: ``` type Animal struct { Species string `json:"species"` Description string `json:"description"` } var animals []Animal ``` Next, define the handler to get all animals : ``` func getAnimalHandler(w http.ResponseWriter, r *http.Request) { //Convert the "animals" variable to json animalListBytes, err := json.Marshal(animals) // If there is an error, print it to the console, and return a server // error response to the user if err != nil { fmt.Println(fmt.Errorf("Error: %v", err)) w.WriteHeader(http.StatusInternalServerError) return } // If all goes well, write the JSON list of animals to the response w.Write(animalListBytes) } ``` Next, the handler to create a new entry of animals : ``` func createAnimalHandler(w http.ResponseWriter, r *http.Request) { // Create a new instance of Animal animal := Animal{} // We send all our data as HTML form data // the `ParseForm` method of the request, parses the // form values err := r.ParseForm() // In case of any error, we respond with an error to the user if err != nil { fmt.Println(fmt.Errorf("Error: %v", err)) w.WriteHeader(http.StatusInternalServerError) return } // Get the information about the animal from the form info animal.Species = r.Form.Get("species") animal.Description = r.Form.Get("description") // Append our existing list of animals with a new entry animals = append(animals, animal) //Finally, we redirect the user to the original HTMl page // (located at `/assets/`), using the http libraries `Redirect` method http.Redirect(w, r, "/assets/", http.StatusFound) } ``` The final stage, is to include these handler to our router, to be able to allow them to use by the app : ``` // These lines are added inside the newRouter() function before returning r r.HandleFunc("/animal", getAnimalHandler).Methods("GET") r.HandleFunc("/animal", createAnimalHandler).Methods("POST") return r ``` The tests regarding the two handlers and also the routing included are similar to the last tests we had written for the GET /hello handler and static file server, and they are still left as an exercise for the readers. ### Summary Up to now, we now have included persistence to the application, using the information about various animals getting saved and retrieved. Nevertheless, that persistence is temporary, because it is in memory space. Which means that at any time you reboot your application, all of the information will get removed. To be able to bring correct persistence, we are going to must add a database to the stack. So far, the code had been simple to reason about and test, as it was obviously a standalone application. Including a database will certainly add an additional layer of communication. We will be going to create a database and connected to our application in the next part of the tutorial <br /><hr/><em>Posted on <a href="https://utopian.io/utopian-io/@exploringworld/build-complete-full-stack-web-app-using-go-programming-language">Utopian.io - Rewarding Open Source Contributors</a></em><hr/>
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":23096959,"name":"go","full_name":"golang/go","html_url":"https://github.com/golang/go","fork":false,"owner":{"login":"golang"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","utopian-io","fullstack","apps","web"]}
Transaction InfoBlock #21976428/Trx abec30cf9980a203ca016036ddfae2f75a5edccb
View Raw JSON Data
{
  "trx_id": "abec30cf9980a203ca016036ddfae2f75a5edccb",
  "block": 21976428,
  "trx_in_block": 66,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-29T00:21:06",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "build-complete-full-stack-web-app-using-go-programming-language",
      "title": "Build Complete Full Stack Web App Using Go Programming Language ",
      "body": "#### Welcome to the First Part of the Tutorial on Build Complete Full Stack Web App Using Go Programming Language \n<center> <img src= https://imgur.com/Rajc7CQ.jpg/> </center>\n\n#### What Will I Learn?\n\n- You will learn how to develop full stack web application using Go\n- You will learn how to create HTTP server and making routes\n- You will learn about static files and their creation\n- Your will learn about the REST API handlers and testing\n\n\n#### Requirements\n##### System Requirements:\n\n- [Go Programming Language]( https://golang.org/dl/) for building App\n- The Basic Command Line\n##### OS Support:\n\n- Windows 7/8/10\n- macOS \n- Linux \n#### Difficulty\n\n\n\n- Intermediate\n\n#### Required Understanding\n- You just need beginner level understanding of the Go programming language.\n- A fair understanding of Programming Languages\n- A thirst for learning and developing something new\n\n\n#### Description\n-\tGo gets increasingly more well-known as the go-to language to develop web based applications.\n-\tAll you need is a little bit of understanding of web design. If you are a web developer and want to build Full Stack Apps, this tutorial is for you.With this particular tutorial, I really hope to get the center ground and provide a single source that explains steps to make a full stack web app in Go, together with adequate test instances.\n#### What is Go Programming Language ?\nGo is an open source programming language which makes it simple to develop easy, dependable, and effective software.\nGo is surely an incredible option for a language as it was developed by a few of the exact same individuals who created the C programming language, Unix, and UTF-8 - probably the most important efforts to computer science. Robert Griesemer, Rob Pike, and Ken Thompson developed Go to become a modern language which easily uses several cores, easily implements concurrency, very easily works in distributed environments, and simply enables the developer to write applications - it has a really lean and user friendly format.\n\n#### What is Full Stack ?\nWe will develop a community encyclopedia of animals. This website will :\n\n-Display the various records submitted through the community, using the name and information on the animal they will located.\n-Permit anyone to post a fresh entry about a animal which they found.\n\nThis application will require three components :\n1.\tThe web server\n2.\tThe front-end app\n3.\tThe database\n### Setting up the environment\nThis section explains how you can set up your own environment and project structure the first time\n\n#### 1. Set up your $GOPATH\nRun this command to check the current value of your `$GOPATH `environment variable :\n`echo $GOPATH`\nIf you do not get a directory name, include the `GOPATH` variable to your environment (you are able to choose any directory location you would like, however it will be much better if you create a brand new directory for this) :\n\n`export GOPATH=\"/location/of/your/gopath/directory\"`\nYou can paste the above line in you `.bashrc `or `.zshrc `file, in case you wish to make the variable to be permanent.\n#### 2. Set up directory structure\nHereafter, the actual **“Go directory”** will certainly make reference to the place described from your `$GOPATH` environment variable. Within the Go directory, you will need to create 3 folders (if they happen to be not there previously) :\n\n```\n# Inside the Go directory\nmkdir src\nmkdir pkg\nmkdir bin\n```\nThe purpose of each directory can be seen from its name:\n• bin - is actually wherever all of the executable binaries produced by compiling your code go\n• pkg - Consists of package objects created by libraries (that you do not have to think about now)\n• src - is actually wherever all of your Go source code will go. Yes, the whole thing. Even which weird side project that you will be thinking of building.\n#### 3. Making your project directory\nThe project folders within the src directory must stick to that exact same location structure since the place wherever your remote repository is situated. So, for instance, if I make a new project known as **“animalpedia”**, and i also make a repository for that below my name on github, in a way that the location of the project repository will be on `github.com/exploringworld/animalpedia`, then the place of this project in the computer could be : \n`$GOPATH/src/github.com/exploringworld/animalpedia`\n\nGo on and create a comparable directory for your project. In case you have not created an online repo yet, simply name the directories based on the location which you intend to put your own code in.\n\nThis particular location on your pc will henceforth become known as your **project directory**\n### Getting HTTP server\n\nWithin your project directory, make a file known as `main.go` inside your project directory :\n\n`touch main.go`\n\nThis particular file will contain the program code to start your server :\n\n```// This is the name of package below\n// Anything within our this package name can see everything\npackage main\n\n// Below are the names of libraries we going to use\n// Both \"fmt\" and \"net\" are part of the Go Language standard library\nimport (\n\t// \"fmt\" has methods for formatted I/O operations\t\"fmt\"\n\t// The \"net/http\" library contains methods to implement HTTP clients and servers\n\t\"net/http\"\n)\n\nfunc main() {\n\t// The \"HandleFunc\" method takes a path and a function as arguments\n\t// (Yes, we can pass functions as arguments, and even treat them like variables in Go Programming language)\n\t// BUT, the handler function has to must have the appropriate signature\n\thttp.HandleFunc(\"/\", handler)\n\n\t// After we define our server, we now \"listen and serve\" on port 8080\n\t// The second argument is the handler, which we will come to later on, but for now it is left as nil,\n\t// and the handler defined above (in \"HandleFunc\") is used\n\thttp.ListenAndServe(\":8080\", nil)\n}\n\n// \"handler\" is our handler function. It has to follow the function signature of a ResponseWriter and Request type\n// as the arguments.\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\t// For this, we would always pipe the \"Hello World\" into the response writer\n\tfmt.Fprintf(w, \"Hello World!\")\n}\n```\n`fmt.Fprintf,` in contrast to another `printf` statements you might know, requires a “writer” as its 1st argument. The 2nd argument will be the data which is piped in to this writer. The outcome therefore seems based on where the writer goes it. In our situation the `ResponseWriter` w writes the output as the response to users request.\n`\n\nYou now run this file :\n`go run main.go`\nAnd navigate to http://localhost:8080 in your browser, or by running the command  through CMD.\n`curl localhost:8080`\nAnd see the code output: **“Hello World!”**\nYou have now successfully started an HTTP server in Go Language.\n### Making the routes\nOur own server is currently operating, but, you may observe that we get exactly the same “Hello World!”response whatever the route we strike, or the HTTP method we utilize. To find out this on your own, run the following curl commands, and take notice of the response that this server will give you :\n```\ncurl localhost:8080/some-other-route\ncurl -X POST localhost:8080\ncurl -X PUT localhost:8080/samething\n```\nAll three commands are still going to give you “Hello World!”\nWe would like to provide our server a bit more intelligence compared to this, to ensure that we are able to manage a number of paths and methods. This is where routing is necessary.\nEven though you are able to accomplish this with Go’s `net/http` standard library, there are many libraries available that offer a more idiomatic as well as declarative method to handle http routing.\n\n### Installing external libraries into Go\nWe are setting up a few external libraries through the following tutorial, in which the standard libraries do not give the features that we desire.\nWhenever we install libraries, we want a way to make sure that others who work with our code also provide exactly the same version of the library that we perform.\nTo do this, we make use of a “package manager” tool. This specific tool acts several purposes:\n•\tIt ensures the versions associated with any external libraries we all install tend to be locked down, to ensure that breaking changes in some of the libraries usually do not affect our program code.\n•\tIt brings the necessary external libraries and stores them locally, in order that various projects may use diverse versions of the same library, when they need to.\n•\tIt stores the names and versions of most our external libraries, so others may set up the same versions which we are working along with on this system.\nThe official package manager for Go (to be more exact “official experiment” which is “safe for production use” as explained on the homepage) is known as dep. You are able to install dep by following the actual setup guide `https://github.com/golang/dep`. You can actually confirm its installation after running :\n\n\n`dep version`\nwhich will output a few information on the particular version when successful.\nIn order to load package management for the project, run the command :\n`dep init`\nThis can produce the` Gopkg.toml` and `Gopkg.lock` files, which are the files which are useful to record and lock dependencies within our project.\nNext, we set up our routing library:\n`dep ensure -add github.com/gorilla/mux`\nThis will add the `gorilla/mux` library to your project.\nRight now, we are able to change the code to work with features this library provides :\n```\npackage main\n\nimport (\n\t// Import the gorilla/mux library we just installed\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/gorilla/mux\"\n)\n\nfunc main() {\n\t// Declare a new router\n\tr := mux.NewRouter()\n\n\t// This is where the router is useful, it allows us to declare methods that\n\t// this path will be valid for\n\tr.HandleFunc(\"/hello\", handler).Methods(\"GET\")\n\n\t// We can then pass our router (after declaring all our routes) to this method\n\t// (where previously, we were leaving the secodn argument as nil)\n\thttp.ListenAndServe(\":8080\", r)\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintf(w, \"Hello World!\")\n}\n```\n### Testing Our Application\nTesting is definitely an important section of building any application **“production quality”**. It makes sure that our app functions like we anticipate that it will.\nLets begin by testing our handler. Create a file named main_test.go:\n```\n//main_test.go\n\npackage main\n\nimport (\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n)\n\nfunc TestHandler(t *testing.T) {\n\t//Here, we form a new HTTP request. This is the request that's going to be\n\t// passed to our handler.\n\t// The first argument is the method, the second argument is the route (which \n\t//we leave blank for now, and will get back to soon), and the third is the \n\t//request body, which we don't have in this case.\n\treq, err := http.NewRequest(\"GET\", \"\", nil)\n\n\t// In case there is an error in forming the request, we fail and stop the test\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We use Go's httptest library to create an http recorder. This recorder\n\t// will act as the target of our http request\n\t// (you can think of it as a mini-browser, which will accept the result of \n\t// the http request that we make)\n\trecorder := httptest.NewRecorder()\n\n\t// Create an HTTP handler from our handler function. \"handler\" is the handler \n\t// function defined in our main.go file that we want to test\n\thf := http.HandlerFunc(handler)\n\n\t// Serve the HTTP request to our recorder. This is the line that actually\n\t// executes our the handler that we want to test\n\thf.ServeHTTP(recorder, req)\n\n\t// Check the status code is what we expect.\n\tif status := recorder.Code; status != http.StatusOK {\n\t\tt.Errorf(\"handler returned wrong status code: got %v want %v\",\n\t\t\tstatus, http.StatusOK)\n\t}\n\n\t// Check the response body is what we expect.\n\texpected := `Hello World!`\n\tactual := recorder.Body.String()\n\tif actual != expected {\n\t\tt.Errorf(\"handler returned unexpected body: got %v want %v\", actual, expected)\n\t}\n}\n```\nGo utilizes a convention that will determines the test file when it has got the pattern `*_test.go`\nTo perform this test, simply run :\ngo test ./...\nfrom the project main directory. You need to see a mild message suggesting that every thing went ok.\n\n### Making our routing to test\nIf you see in our earlier snippet, we kept the **“route”** empty while creating the mock request applying `http.newRequest`. So how exactly does this particular test continue to pass if your handler will be defined just for `“GET /handler”` route?\nWell, ends up this test was just testing our handler and not the actual routing to the handler. In other words, which means that the above mentioned test makes sure that the request arriving will get functioned properly provided that it is sent to the right handler.\nIn this portion, we are going to test this routing, to ensure that we are able to make sure that every handler will be mapped on the correct HTTP route.\nPrior to we continue to test our routing, it is essential to ensure that the code can be analyzed for this. Change the main.go file to appear like this:\n```\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/gorilla/mux\"\n)\n\n// The new router function creates the router and\n// returns it to us. We can now use this function\n// to instantiate and test the router outside of the main function\nfunc newRouter() *mux.Router {\n\tr := mux.NewRouter()\n\tr.HandleFunc(\"/hello\", handler).Methods(\"GET\")\n\treturn r\n}\n\nfunc main() {\n\t// The router is now formed by calling the `newRouter` constructor function\n\t// that we defined above. The rest of the code stays the same\n\tr := newRouter()\n\thttp.ListenAndServe(\":8080\", r)\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintf(w, \"Hello World!\")\n}\n```\nNow  our route constructor function is separated, let us see test our routing:\n```\nfunc TestRouter(t *testing.T) {\n\t// Instantiate the router using the constructor function that\n\t// we defined previously\n\tr := newRouter()\n\n\t// Create a new server using the \"httptest\" libraries `NewServer` method\n\t// Documentation : https://golang.org/pkg/net/http/httptest/#NewServer\n\tmockServer := httptest.NewServer(r)\n\n\t// The mock server we created runs a server and exposes its location in the\n\t// URL attribute\n\t// We make a GET request to the \"hello\" route we defined in the router\n\tresp, err := http.Get(mockServer.URL + \"/hello\")\n\n\t// Handle any unexpected error\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We want our status to be 200 (ok)\n\tif resp.StatusCode != http.StatusOK {\n\t\tt.Errorf(\"Status should be ok, got %d\", resp.StatusCode)\n\t}\n\n\t// In the next few lines, the response body is read, and converted to a string\n\tdefer resp.Body.Close()\n\t// read the body into a bunch of bytes (b)\n\tb, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\t// convert the bytes to a string\n\trespString := string(b)\n\texpected := \"Hello World!\"\n\n\t// We want our response to match the one defined in our handler.\n\t// If it does happen to be \"Hello world!\", then it confirms, that the\n\t// route is correct\n\tif respString != expected {\n\t\tt.Errorf(\"Response should be %s, got %s\", expected, respString)\n\t}\n\n}\n```\nNow we all know that each time we hit the actual `GET /hello route`, we have a response of hello world. When we hit some other route, it should respond having a 404. Actually, let us write a test for exactly this condition :\n```\nfunc TestRouterForNonExistentRoute(t *testing.T) {\n\tr := newRouter()\n\tmockServer := httptest.NewServer(r)\n\t// Most of the code is similar. The only difference is that now we make a \n\t//request to a route we know we didn't define, like the `POST /hello` route.\n\tresp, err := http.Post(mockServer.URL+\"/hello\", \"\", nil)\n\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We want our status to be 405 (method not allowed)\n\tif resp.StatusCode != http.StatusMethodNotAllowed {\n\t\tt.Errorf(\"Status should be 405, got %d\", resp.StatusCode)\n\t}\n\n\t// The code to test the body is also mostly the same, except this time, we \n\t// expect an empty body\n\tdefer resp.Body.Close()\n\tb, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\trespString := string(b)\n\texpected := \"\"\n\n\tif respString != expected {\n\t\tt.Errorf(\"Response should be %s, got %s\", expected, respString)\n\t}\n\n}\n```\nSince we have figured out how you can make a simple http server, we are able to serve static files from this for the users to interact with.\n### Serving the Assets files\n**“Static files”** are the HTML, CSS, JavaScript, images, and also the additional static asset files which are required to form a web site.\nYou will find 3 actions we must take in so that it will create our server.Now serve these types oo static assets.\n1.\tMake static assets\n2.\tChange our router in order to assist static assets\n3.\tInclude tests to confirm our new server can easily serve static files\n#### Create static assets\nTo create static assets, make a directory in your project root directory, and name it `assets` :\n`mkdir assets`\nFollowing, create an HTML file within this directory. This is actually the file we will serve, together with any file which goes in the assets directory :\n`touch assets/index.html`\n#### Modify the router\nInterestingly sufficient, the whole file server could be enabled in only adding Three lines of code within the router. The newest router constructor may be like this :\n```\nfunc newRouter() *mux.Router {\n\tr := mux.NewRouter()\n\tr.HandleFunc(\"/hello\", handler).Methods(\"GET\")\n\n\t// Declare the static file directory and point it to the \n\t// directory we just made\n\tstaticFileDirectory := http.Dir(\"./assets/\")\n\t// Declare the handler, that routes requests to their respective filename.\n\t// The fileserver is wrapped in the `stripPrefix` method, because we want to\n\t// remove the \"/assets/\" prefix when looking for files.\n\t// For example, if we type \"/assets/index.html\" in our browser, the file server\n\t// will look for only \"index.html\" inside the directory declared above.\n\t// If we did not strip the prefix, the file server would look for \n\t// \"./assets/assets/index.html\", and yield an error\n\tstaticFileHandler := http.StripPrefix(\"/assets/\", http.FileServer(staticFileDirectory))\n\t// The \"PathPrefix\" method acts as a matcher, and matches all routes starting\n\t// with \"/assets/\", instead of the absolute route itself\n\tr.PathPrefix(\"/assets/\").Handler(staticFileHandler).Methods(\"GET\")\n\treturn r\n}\n```\n#### Testing of static file server\nIt's hard to really say that you will have finished a feature unless you possess tests for it. We can easily check the static file server by having another test function to main_test.go :\n```\nfunc TestStaticFileServer(t *testing.T) {\n\tr := newRouter()\n\tmockServer := httptest.NewServer(r)\n\n\t// We want to hit the `GET /assets/` route to get the index.html file response\n\tresp, err := http.Get(mockServer.URL + \"/assets/\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// We want our status to be 200 (ok)\n\tif resp.StatusCode != http.StatusOK {\n\t\tt.Errorf(\"Status should be 200, got %d\", resp.StatusCode)\n\t}\n\n\t// It isn't wise to test the entire content of the HTML file.\n\t// Instead, we test that the content-type header is \"text/html; charset=utf-8\"\n\t// so that we know that an html file has been served\n\tcontentType := resp.Header.Get(\"Content-Type\")\n\texpectedContentType := \"text/html; charset=utf-8\"\n\n\tif expectedContentType != contentType {\n\t\tt.Errorf(\"Wrong content type, expected %s, got %s\", expectedContentType, contentType)\n\t}\n\n}\n```\nTo actually test your work, run the server :\n`go run main.go`\nthen, navigate to http://localhost:8080/assets/ in your web browser.\n#### Making of web browser application\nBecause we have to make our animal encyclopedia, lets make a simple HTML file which shows record of animals, as well as brings the list from an API on-page load, plus offers a form to up-date checklist of animals:\n```\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <title>The animal encyclopedia</title>\n</head>\n\n<body>\n  <h1>The animal encyclopedia</h1>\n  <!-- \n    This section of the document specifies the table that will\n    be used to display the list of animals and their description\n   -->\n  <table>\n    <tr>\n      <th>Species</th>\n      <th>Description</th>\n    </tr>\n    <td>Lion</td>\n    <td>Common between cities</td>\n    </tr>\n  </table>\n  <br/>\n\n  <!-- \n    This section contains the form, that will be used to hit the \n    `POST /animal` API that we will build in the next section\n   -->\n  <form action=\"/animal\" method=\"post\">\n    Species:\n    <input type=\"text\" name=\"species\">\n    <br/> Description:\n    <input type=\"text\" name=\"description\">\n    <br/>\n    <input type=\"submit\" value=\"Submit\">\n  </form>\n\n  <!-- \n    Finally, the last section is the script that will\n    run on each page load to fetch the list of animals\n    and add them to our existing table\n   -->\n  <script>\n    animalTable = document.querySelector(\"table\")\n\n    /*\n    Use the browsers `fetch` API to make a GET call to /animal\n    We expect the response to be a JSON list of animals, of the\n    form :\n    [\n      {\"species\":\"...\",\"description\":\"...\"},\n      {\"species\":\"...\",\"description\":\"...\"}\n    ]\n    */\n    fetch(\"/animal\")\n      .then(response => response.json())\n      .then(animalList => {\n        //Once we fetch the list, we iterate over it\n        animalList.forEach(animal => {\n          // Create the table row\n          row = document.createElement(\"tr\")\n\n          // Create the table data elements for the species and\n\t\t\t\t\t// description columns\n          species = document.createElement(\"td\")\n          species.innerHTML = animal.species\n          description = document.createElement(\"td\")\n          description.innerHTML = animal.description\n\n          // Add the data elements to the row\n          row.appendChild(species)\n          row.appendChild(description)\n          // Finally, add the row element to the table itself\n          animalTable.appendChild(row)\n        })\n      })\n  </script>\n</body>\n```\n### Addition of animal REST API handlers\nWe are able to see, we will have to apply 2 APIs to ensure that this app to function:\n1. GET /animal - which will retrieve record of all animals presently within the system\n2. POST /animal - which will create an entrance to the current set of animals\nIn this, we are going to write the related handlers.\nCreate a new file named animal_handlers.go, next to the main.go file.\nInitially, we are going to include the definition of the Animal struct as well as initialize a common animal variable:\n```\ntype Animal struct {\n\tSpecies     string `json:\"species\"`\n\tDescription string `json:\"description\"`\n}\n\nvar animals []Animal\n```\nNext, define the handler to get all animals :\n```\nfunc getAnimalHandler(w http.ResponseWriter, r *http.Request) {\n\t//Convert the \"animals\" variable to json\n\tanimalListBytes, err := json.Marshal(animals)\n\n\t// If there is an error, print it to the console, and return a server\n\t// error response to the user\n\tif err != nil {\n\t\tfmt.Println(fmt.Errorf(\"Error: %v\", err))\n\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\treturn\n\t}\n\t// If all goes well, write the JSON list of animals to the response\n\tw.Write(animalListBytes)\n}\n```\nNext, the handler to create a new entry of animals :\n```\nfunc createAnimalHandler(w http.ResponseWriter, r *http.Request) {\n\t// Create a new instance of Animal\n\tanimal := Animal{}\n\n\t// We send all our data as HTML form data\n\t// the `ParseForm` method of the request, parses the\n\t// form values\n\terr := r.ParseForm()\n\n\t// In case of any error, we respond with an error to the user\n\tif err != nil {\n\t\tfmt.Println(fmt.Errorf(\"Error: %v\", err))\n\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\t// Get the information about the animal from the form info\n\tanimal.Species = r.Form.Get(\"species\")\n\tanimal.Description = r.Form.Get(\"description\")\n\n\t// Append our existing list of animals with a new entry\n\tanimals = append(animals, animal)\n\n\t//Finally, we redirect the user to the original HTMl page\n\t// (located at `/assets/`), using the http libraries `Redirect` method\n\thttp.Redirect(w, r, \"/assets/\", http.StatusFound)\n}\n```\nThe final stage, is to include these handler to our router, to be able to allow them to use by the app :\n```\n\t// These lines are added inside the newRouter() function before returning r\n\tr.HandleFunc(\"/animal\", getAnimalHandler).Methods(\"GET\")\n\tr.HandleFunc(\"/animal\", createAnimalHandler).Methods(\"POST\")\n\treturn r\n```\nThe tests regarding the two handlers and also the routing included are similar to the last tests we had written for the GET /hello handler and static file server, and they are still left as an exercise for the readers.\n\n### Summary\nUp to now, we now have included persistence to the application, using the information about various animals getting saved and retrieved.\nNevertheless, that persistence is temporary, because it is in memory space. Which means that at any time you reboot your application, all of the information will get removed. To be able to bring correct persistence, we are going to must add a database to the stack.\nSo far, the code had been simple to reason about and test, as it was obviously a standalone application. Including a database will certainly add an additional layer of communication.\nWe will be going to create a database and connected to our application in the next part of the tutorial\n\n\n<br /><hr/><em>Posted on <a href=\"https://utopian.io/utopian-io/@exploringworld/build-complete-full-stack-web-app-using-go-programming-language\">Utopian.io -  Rewarding Open Source Contributors</a></em><hr/>",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":23096959,\"name\":\"go\",\"full_name\":\"golang/go\",\"html_url\":\"https://github.com/golang/go\",\"fork\":false,\"owner\":{\"login\":\"golang\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"utopian-io\",\"fullstack\",\"apps\",\"web\"]}"
    }
  ]
}
2018/04/28 03:32:09
parent authorexploringworld
parent permlinkdevelop-mobile-apps-using-ionic-framework-part-2
authorrosatravels
permlinkre-exploringworld-develop-mobile-apps-using-ionic-framework-part-2-20180428t033201709z
title
bodyHi @exploringworld, Thank you for your contribution but unfortunately we are unable to accept your video tutorial. In video tutorial, your presentation needs to be organized with clarity of speech. Most of the time, I am not able to understand what you are saying. If people do not know what you are saying, there is no value in the video. You need to work on diction with correct pronunciation of words so that learners can follow along. One of the guidelines in Utopian is that the presenter must speak clearly and professionally. This is something that you need to work on before submitting more video tutorials. If you have questions, please contact us at Discord. ---------------------------------------------------------------------- Need help? Write a ticket on https://support.utopian.io. Chat with us on [Discord](https://discord.gg/uTyJkNm). **[[utopian-moderator]](https://utopian.io/moderators)**
json metadata{"tags":["utopian-io"],"community":"utopian","app":"utopian/1.0.0"}
Transaction InfoBlock #21951452/Trx 7ebc886c7e7ef9fd30d7bcfb7d0d22edb992cbd8
View Raw JSON Data
{
  "trx_id": "7ebc886c7e7ef9fd30d7bcfb7d0d22edb992cbd8",
  "block": 21951452,
  "trx_in_block": 16,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-28T03:32:09",
  "op": [
    "comment",
    {
      "parent_author": "exploringworld",
      "parent_permlink": "develop-mobile-apps-using-ionic-framework-part-2",
      "author": "rosatravels",
      "permlink": "re-exploringworld-develop-mobile-apps-using-ionic-framework-part-2-20180428t033201709z",
      "title": "",
      "body": "Hi @exploringworld,\n\nThank you for your contribution but unfortunately we are unable to accept your video tutorial.\n\nIn video tutorial, your presentation needs to be organized with clarity of speech.  Most of the time, I am not able to understand what you are saying.  If people do not know what you are saying, there is no value in the video.   You need to work on diction with correct pronunciation of words so that learners can follow along.  \n\nOne of the guidelines in Utopian is that the presenter must speak clearly and professionally.  This is something that you need to work on before submitting more video tutorials.\n\nIf you have questions, please contact us at Discord.\n\n----------------------------------------------------------------------\nNeed help? Write a ticket on https://support.utopian.io.\nChat with us on [Discord](https://discord.gg/uTyJkNm).\n\n**[[utopian-moderator]](https://utopian.io/moderators)**",
      "json_metadata": "{\"tags\":[\"utopian-io\"],\"community\":\"utopian\",\"app\":\"utopian/1.0.0\"}"
    }
  ]
}
2018/04/28 03:25:30
parent author
parent permlinkutopian-io
authorexploringworld
permlinkdevelop-mobile-apps-using-ionic-framework-part-2
titleDevelop Mobile Apps Using Ionic Framework Part-2
body#### Welcome to the Second Video Tutorial of Mobile Apps Development using Ionic Framework <center> <img src= https://imgur.com/hByL8VX.jpg/> </center> #### What Will I Learn? - You will learn how to develop amazing mobile apps using **Ionic Framework** and **Cordova** - You will learn the working of **folder and files** of Ionic Framework - You will learn about **Ionic header, Ionic content and Ionic footer** - Your will learn about **app.js** and **controllers.js** files - Your will learn regarding **ionic classes and ion pain** usage #### Requirements ##### System Requirements: - [Node.js](https://nodejs.org/en/) for building apps - [Visual Studio Code](https://code.visualstudio.com/) for code editing - [Git](https://git-scm.com/downloads) **(Optional)** or Command Prompt or Terminal - An Android or iOS Emulator or mobile device for testing ##### OS Support: - Windows 7/8/10 - macOS - Linux #### Difficulty - Intermediate #### Required Understanding - You just need a little bit of knowledge of HTML,CSS and JS - A fair understanding of Programming - A thirst for learning and developing something new #### Description - This particular video tutorial Series is for everyone who would like to build amazing Android and iOS apps. In this tutorial, you will learn about Ionic Framework with AngularJS from the beginning, that allows you to develop amazing mobile apps with just **HTML, CSS** and **JS**. - All you need is a little bit of understanding of web design . If you are a web developer and want to build mobile apps, Ionic will probably be your piece of cake. You will be able to create amazing apps that will work on both Android and iOS. #### What is Ionic Framework ? Ionic is an HTML5 mobile app development framework targeted at building hybrid mobile apps. Hybrid apps are essentially small websites running in a browser shell in an app that have access to the native platform layer. Hybrid apps have many benefits over pure native apps, specifically in terms of platform support, speed of development, and access to 3rd party code. Think of Ionic as the front-end UI framework that handles all of the look and feel and UI interactions your app needs in order to be compelling. Kind of like **“Bootstrap for Native”** but with support for a broad range of common native mobile components, slick animations, and beautiful design. [Source](https://ionicframework.com/docs/v1/guide/preface.html) #### Some of the key steps that are used in this tutorial *_Below I discuss important coding steps that are must required in this video tutorial_* ##### STEP 1: Now we have learn about how to develop apps using ionic and also how to deploy them on platform. Now we open the `index.html`file In the visual studio code and then at the bottom there is a **body** tag in which there is `<ion-pain>` which contains `<ion-header>` and `<ion-content>` tags, ion-content is basically a container which helps you to organize your content.It allows you to encapsulate your data <center> <img src= https://imgur.com/KS8yvPr.jpg/> </center> ##### STEP 2: Now inside the `<ion-pain>` tag we are going to change the title of our `header` as well as the `class` of our header. To change the color of our header classes provide different types of color combinations for our **headers** So we change the title to **First App** and change the class to `bar-positive`which turns the color of our header to nice blue color. <center> <img src= https://imgur.com/m3jPryB.jpg/> </center> <center> <img src= https://imgur.com/BpkkQrq.jpg/> </center> ##### STEP 3: We can use `<div>` container here as well in place of `<ion-header-bar>`So it will be easier for us to add more functionality easily <center> <img src= https://imgur.com/GgWANt2.jpg/> </center> <center> <img src= https://imgur.com/w8nM9K6.jpg/> </center> ##### STEP 4: Now we can also use `<div>`tag to define footer at the end of the code by using `bar bar-footer bar-calm` tag which defines a cool footer with a blue color at the bottom of our app showing in the emulator and named as **This is the footer** <center> <img src= https://imgur.com/xHK0rgp.jpg/> </center> <center> <img src=https://imgur.com/4GMVCRE.jpg/> </center> _*So our changes in the header and footer classes will look like this*_ <center> <img src= https://imgur.com/x9KEFpY.jpg/> </center> #### Video Tutorial https://youtu.be/VBRHXQbdjDA #### Curriculum This video is second video of the Develop Mobile Apps Using Ionic Framework Series. You can see the first part with the link down below - [Develop Mobile Apps Using Ionic Framework Part-1]( https://utopian.io/utopian-io/@exploringworld/qnj1e-develop-mobile-apps-using-ionic-framework-part-1) <br /><hr/><em>Posted on <a href="https://utopian.io/utopian-io/@exploringworld/develop-mobile-apps-using-ionic-framework-part-2">Utopian.io - Rewarding Open Source Contributors</a></em><hr/>
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":12256376,"name":"ionic","full_name":"ionic-team/ionic","html_url":"https://github.com/ionic-team/ionic","fork":false,"owner":{"login":"ionic-team"}},"pullRequests":[],"platform":"github","type":"video-tutorials","tags":["utopian-io","utopian-io","mobileapps","ionic","tutorial"],"users":["exploringworld"],"links":["https://nodejs.org/en/","https://code.visualstudio.com/","https://git-scm.com/downloads","https://ionicframework.com/docs/v1/guide/preface.html"],"moderator":{"account":"rosatravels","time":"2018-04-28T03:25:30.113Z","pending":false,"reviewed":false,"flagged":true},"questions":null,"score":null,"total_influence":null,"staff_pick":null,"staff_pick_by":null,"config":{"questions":[{"question":"How many substantial concepts does this tutorial address?","question_id":"vtuts-1","answers":[{"answer":"4-5 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-1","value":10},{"answer":"2-3 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-2","value":5},{"answer":"1 substantial concept covered in the tutorial.","answer_id":"vtuts-1-a-3","value":2},{"answer":"More than 5 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-4","value":0}]},{"question":"How informative is the content included alongside the video?","question_id":"vtuts-2","answers":[{"answer":"Exceptionally good text and, when applicable, images for concepts covered.","answer_id":"vtuts-2-a-1","value":10},{"answer":"Thorough text and, if applicable, images for concepts covered.","answer_id":"vtuts-2-a-2","value":5},{"answer":"Minimal text and images.","answer_id":"vtuts-2-a-3","value":3},{"answer":"No or very little text and images.","answer_id":"vtuts-2-a-4","value":0}]},{"question":"Is the video clearly prepared and structured?","question_id":"vtuts-3","answers":[{"answer":"Both the presenter and the video are exceptionally organized, structured and presented","answer_id":"vtuts-3-a-1","value":20},{"answer":"Presenter is prepared and video concepts are structured.","answer_id":"vtuts-3-a-2","value":16},{"answer":"Presenter has moments when he/she seems unprepared and/or the content seems to be unstructured.","answer_id":"vtuts-3-a-3","value":8},{"answer":"Presenter seems unprepared and/or video is unstructured.","answer_id":"vtuts-3-a-4","value":0}]},{"question":"Does the contributor provide supplementary resources, such as code and sample files in the contribution post or a GitHub repository?","question_id":"vtuts-4","answers":[{"answer":"Contributor provided exceptional supplementary resources.","answer_id":"vtuts-4-a-1","value":5},{"answer":"Contributor provided good supplementary resources.","answer_id":"vtuts-4-a-2","value":4},{"answer":"Contributor provided minimal supplementary resources.","answer_id":"vtuts-4-a-3","value":1.5},{"answer":"No supplementary resources were provided.","answer_id":"vtuts-4-a-4","value":0}]},{"question":"How would you describe the sound quality of the video?","question_id":"vtuts-5","answers":[{"answer":"Sound quality is excellent and sounds professionally produced.","answer_id":"vtuts-5-a-1","value":10},{"answer":"The sound is clear and understandable with complimenting background music / sounds.","answer_id":"vtuts-5-a-2","value":7},{"answer":"Low quality of sound and/or mildly distracting background noise.","answer_id":"vtuts-5-a-3","value":3},{"answer":"Distracting background noise and/or very low quality recording.","answer_id":"vtuts-5-a-4","value":0}]},{"question":"Does the presenter speak clearly and is easy to understand?","question_id":"vtuts-6","answers":[{"answer":"Yes, presenter’s speech is highly engaging and professional.","answer_id":"vtuts-6-a-1","value":10},{"answer":"Yes, the voice-over is easy to understand.","answer_id":"vtuts-6-a-2","value":7},{"answer":"Only some of the voice-over was comprehensible.","answer_id":"vtuts-6-a-3","value":2},{"answer":"The voice-over was impossible to understand / not included at all.","answer_id":"vtuts-6-a-4","value":0}]},{"question":"Are the title of the tutorial and the concepts being covered present on the video in text overlay form?","question_id":"vtuts-7","answers":[{"answer":"Title and concepts covered are present in the video at all times in a non-disruptive way.","answer_id":"vtuts-7-a-1","value":5},{"answer":"Title and concepts covered appear temporarily when they are addressed.","answer_id":"vtuts-7-a-2","value":4.5},{"answer":"Only the title is presented and the concepts shown are not addressed in overlay text.","answer_id":"vtuts-7-a-3","value":2},{"answer":"Neither title nor concepts covered are presented in the video text overlay.","answer_id":"vtuts-7-a-4","value":0}]},{"question":"How would you describe the formatting, language and overall presentation of the post?","question_id":"c-1","answers":[{"answer":"The post is of very high quality.","answer_id":"c-1-a-1","value":10},{"answer":"The post is of decent quality, but not spectacular in any way.","answer_id":"c-1-a-2","value":7},{"answer":"The post is poorly written and/or formatted, but readable.","answer_id":"c-1-a-3","value":3},{"answer":"The post is really hard to read and the content is barely understandable.","answer_id":"c-1-a-4","value":0}]},{"question":"How would you rate the overall value of this contribution on the open source community and ecosystem?","question_id":"c-2","answers":[{"answer":"This contribution brings great and impactful value, and can be used for applications outside the specific project.","answer_id":"c-2-a-1","value":20},{"answer":"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.","answer_id":"c-2-a-2","value":16},{"answer":"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.","answer_id":"c-2-a-3","value":8},{"answer":"This contribution adds no value to the open source community and ecosystem or the specific project.","answer_id":"c-2-a-4","value":0}]}]}}
Transaction InfoBlock #21951319/Trx 1860129fb61a0fec201e5f5c500597d5f66d58cc
View Raw JSON Data
{
  "trx_id": "1860129fb61a0fec201e5f5c500597d5f66d58cc",
  "block": 21951319,
  "trx_in_block": 33,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-28T03:25:30",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "develop-mobile-apps-using-ionic-framework-part-2",
      "title": "Develop Mobile Apps Using Ionic Framework Part-2",
      "body": "#### Welcome to the Second Video Tutorial of Mobile Apps Development using Ionic Framework\n<center> <img src= https://imgur.com/hByL8VX.jpg/> </center>\n\n#### What Will I Learn?\n\n- You will learn how to develop amazing mobile apps using **Ionic Framework** and **Cordova**\n- You will learn the working of **folder and files** of Ionic Framework\n- You will learn about **Ionic header, Ionic content and Ionic footer**\n- Your will learn about **app.js** and **controllers.js** files\n- Your will learn regarding **ionic classes and ion pain** usage\n\n\n\n#### Requirements\n##### System Requirements:\n\n- [Node.js](https://nodejs.org/en/) for building apps\n- [Visual Studio Code](https://code.visualstudio.com/) for code editing \n- [Git](https://git-scm.com/downloads) **(Optional)** or Command Prompt or Terminal\n- An Android or iOS Emulator or mobile device for testing\n##### OS Support:\n\n- Windows 7/8/10\n- macOS \n- Linux \n#### Difficulty\n\n\n\n- Intermediate\n\n#### Required Understanding\n- You just need a little bit of knowledge of HTML,CSS and JS\n- A fair understanding of Programming \n- A thirst for learning and developing something new\n\n\n#### Description\n-\tThis particular video tutorial Series is for everyone who would like to build amazing Android and iOS apps. In this tutorial, you will learn about Ionic Framework with AngularJS from the beginning, that allows you to develop amazing mobile apps with just **HTML, CSS** and **JS**.\n-\tAll you need is a little bit of understanding of web design\t . If you are a web developer and want to build mobile apps, Ionic will probably be your piece of cake. You will be able to create amazing apps that will work on both Android and iOS.\n#### What is Ionic Framework ?\nIonic is an HTML5 mobile app development framework targeted at building hybrid mobile apps. Hybrid apps are essentially small websites running in a browser shell in an app that have access to the native platform layer. Hybrid apps have many benefits over pure native apps, specifically in terms of platform support, speed of development, and access to 3rd party code.\nThink of Ionic as the front-end UI framework that handles all of the look and feel and UI interactions your app needs in order to be compelling. Kind of like **“Bootstrap for Native”** but with support for a broad range of common native mobile components, slick animations, and beautiful design. [Source](https://ionicframework.com/docs/v1/guide/preface.html)\n#### Some of the key steps that are used in this tutorial\n*_Below I discuss important coding steps that are must required in this video tutorial_*\n##### STEP 1:\nNow we have learn about how to develop apps using ionic and also \nhow to deploy them on platform. Now we open the `index.html`file \nIn the visual studio code and then at the bottom there is a **body**\ntag in which there is `<ion-pain>` which contains `<ion-header>` and `<ion-content>` tags, ion-content is basically a container which helps you to organize your content.It allows you to encapsulate your data\n<center> <img src= https://imgur.com/KS8yvPr.jpg/> </center>\n\n##### STEP 2:\nNow inside the `<ion-pain>` tag we are going to change the title of our `header` as well as the `class` of our header. To change the color of our header classes provide different types of color combinations for our **headers**\nSo we change the title to **First App** and change the class to `bar-positive`which turns the color of our header to nice blue color.\n<center> <img src= https://imgur.com/m3jPryB.jpg/> </center>\n\n\n<center> <img src= https://imgur.com/BpkkQrq.jpg/> </center>\n\n##### STEP 3:\nWe can use  `<div>` container here as well in place of `<ion-header-bar>`So it will be easier for us to add more functionality easily\n<center> <img src= https://imgur.com/GgWANt2.jpg/> </center>\n\n\n<center> <img src= https://imgur.com/w8nM9K6.jpg/> </center>\n\n##### STEP 4:\nNow we can also use `<div>`tag to define footer at the end of the code by using `bar bar-footer bar-calm` tag which defines a cool footer with a blue color at the bottom of our app showing in the emulator and named as **This is the footer**\n<center> <img src= https://imgur.com/xHK0rgp.jpg/> </center>\n\n\n<center> <img src=https://imgur.com/4GMVCRE.jpg/> </center>\n\n_*So our changes in the header and footer classes will look like this*_\n<center> <img src= https://imgur.com/x9KEFpY.jpg/> </center>\n\n\n#### Video Tutorial\nhttps://youtu.be/VBRHXQbdjDA\n#### Curriculum\nThis video is second video of the Develop Mobile Apps Using Ionic Framework Series. You can see the first part with the link down below\n- [Develop Mobile Apps Using Ionic Framework Part-1]( https://utopian.io/utopian-io/@exploringworld/qnj1e-develop-mobile-apps-using-ionic-framework-part-1) \n\n\n\n<br /><hr/><em>Posted on <a href=\"https://utopian.io/utopian-io/@exploringworld/develop-mobile-apps-using-ionic-framework-part-2\">Utopian.io -  Rewarding Open Source Contributors</a></em><hr/>",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":12256376,\"name\":\"ionic\",\"full_name\":\"ionic-team/ionic\",\"html_url\":\"https://github.com/ionic-team/ionic\",\"fork\":false,\"owner\":{\"login\":\"ionic-team\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"video-tutorials\",\"tags\":[\"utopian-io\",\"utopian-io\",\"mobileapps\",\"ionic\",\"tutorial\"],\"users\":[\"exploringworld\"],\"links\":[\"https://nodejs.org/en/\",\"https://code.visualstudio.com/\",\"https://git-scm.com/downloads\",\"https://ionicframework.com/docs/v1/guide/preface.html\"],\"moderator\":{\"account\":\"rosatravels\",\"time\":\"2018-04-28T03:25:30.113Z\",\"pending\":false,\"reviewed\":false,\"flagged\":true},\"questions\":null,\"score\":null,\"total_influence\":null,\"staff_pick\":null,\"staff_pick_by\":null,\"config\":{\"questions\":[{\"question\":\"How many substantial concepts does this tutorial address?\",\"question_id\":\"vtuts-1\",\"answers\":[{\"answer\":\"4-5 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-1\",\"value\":10},{\"answer\":\"2-3 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-2\",\"value\":5},{\"answer\":\"1 substantial concept covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-3\",\"value\":2},{\"answer\":\"More than 5 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-4\",\"value\":0}]},{\"question\":\"How informative is the content included alongside the video?\",\"question_id\":\"vtuts-2\",\"answers\":[{\"answer\":\"Exceptionally good text and, when applicable, images for concepts covered.\",\"answer_id\":\"vtuts-2-a-1\",\"value\":10},{\"answer\":\"Thorough text and, if applicable, images for concepts covered.\",\"answer_id\":\"vtuts-2-a-2\",\"value\":5},{\"answer\":\"Minimal text and images.\",\"answer_id\":\"vtuts-2-a-3\",\"value\":3},{\"answer\":\"No or very little text and images.\",\"answer_id\":\"vtuts-2-a-4\",\"value\":0}]},{\"question\":\"Is the video clearly prepared and structured?\",\"question_id\":\"vtuts-3\",\"answers\":[{\"answer\":\"Both the presenter and the video are exceptionally organized, structured and presented\",\"answer_id\":\"vtuts-3-a-1\",\"value\":20},{\"answer\":\"Presenter is prepared and video concepts are structured.\",\"answer_id\":\"vtuts-3-a-2\",\"value\":16},{\"answer\":\"Presenter has moments when he/she seems unprepared and/or the content seems to be unstructured.\",\"answer_id\":\"vtuts-3-a-3\",\"value\":8},{\"answer\":\"Presenter seems unprepared and/or video is unstructured.\",\"answer_id\":\"vtuts-3-a-4\",\"value\":0}]},{\"question\":\"Does the contributor provide supplementary resources, such as code and sample files in the contribution post or a GitHub repository?\",\"question_id\":\"vtuts-4\",\"answers\":[{\"answer\":\"Contributor provided exceptional supplementary resources.\",\"answer_id\":\"vtuts-4-a-1\",\"value\":5},{\"answer\":\"Contributor provided good supplementary resources.\",\"answer_id\":\"vtuts-4-a-2\",\"value\":4},{\"answer\":\"Contributor provided minimal supplementary resources.\",\"answer_id\":\"vtuts-4-a-3\",\"value\":1.5},{\"answer\":\"No supplementary resources were provided.\",\"answer_id\":\"vtuts-4-a-4\",\"value\":0}]},{\"question\":\"How would you describe the sound quality of the video?\",\"question_id\":\"vtuts-5\",\"answers\":[{\"answer\":\"Sound quality is excellent and sounds professionally produced.\",\"answer_id\":\"vtuts-5-a-1\",\"value\":10},{\"answer\":\"The sound is clear and understandable with complimenting background music / sounds.\",\"answer_id\":\"vtuts-5-a-2\",\"value\":7},{\"answer\":\"Low quality of sound and/or mildly distracting background noise.\",\"answer_id\":\"vtuts-5-a-3\",\"value\":3},{\"answer\":\"Distracting background noise and/or very low quality recording.\",\"answer_id\":\"vtuts-5-a-4\",\"value\":0}]},{\"question\":\"Does the presenter speak clearly and is easy to understand?\",\"question_id\":\"vtuts-6\",\"answers\":[{\"answer\":\"Yes, presenter’s speech is highly engaging and professional.\",\"answer_id\":\"vtuts-6-a-1\",\"value\":10},{\"answer\":\"Yes, the voice-over is easy to understand.\",\"answer_id\":\"vtuts-6-a-2\",\"value\":7},{\"answer\":\"Only some of the voice-over was comprehensible.\",\"answer_id\":\"vtuts-6-a-3\",\"value\":2},{\"answer\":\"The voice-over was impossible to understand / not included at all.\",\"answer_id\":\"vtuts-6-a-4\",\"value\":0}]},{\"question\":\"Are the title of the tutorial and the concepts being covered present on the video in text overlay form?\",\"question_id\":\"vtuts-7\",\"answers\":[{\"answer\":\"Title and concepts covered are present in the video at all times in a non-disruptive way.\",\"answer_id\":\"vtuts-7-a-1\",\"value\":5},{\"answer\":\"Title and concepts covered appear temporarily when they are addressed.\",\"answer_id\":\"vtuts-7-a-2\",\"value\":4.5},{\"answer\":\"Only the title is presented and the concepts shown are not addressed in overlay text.\",\"answer_id\":\"vtuts-7-a-3\",\"value\":2},{\"answer\":\"Neither title nor concepts covered are presented in the video text overlay.\",\"answer_id\":\"vtuts-7-a-4\",\"value\":0}]},{\"question\":\"How would you describe the formatting, language and overall presentation of the post?\",\"question_id\":\"c-1\",\"answers\":[{\"answer\":\"The post is of very high quality.\",\"answer_id\":\"c-1-a-1\",\"value\":10},{\"answer\":\"The post is of decent quality, but not spectacular in any way.\",\"answer_id\":\"c-1-a-2\",\"value\":7},{\"answer\":\"The post is poorly written and/or formatted, but readable.\",\"answer_id\":\"c-1-a-3\",\"value\":3},{\"answer\":\"The post is really hard to read and the content is barely understandable.\",\"answer_id\":\"c-1-a-4\",\"value\":0}]},{\"question\":\"How would you rate the overall value of this contribution on the open source community and ecosystem?\",\"question_id\":\"c-2\",\"answers\":[{\"answer\":\"This contribution brings great and impactful value, and can be used for applications outside the specific project.\",\"answer_id\":\"c-2-a-1\",\"value\":20},{\"answer\":\"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.\",\"answer_id\":\"c-2-a-2\",\"value\":16},{\"answer\":\"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.\",\"answer_id\":\"c-2-a-3\",\"value\":8},{\"answer\":\"This contribution adds no value to the open source community and ecosystem or the specific project.\",\"answer_id\":\"c-2-a-4\",\"value\":0}]}]}}"
    }
  ]
}
2018/04/28 03:25:12
parent author
parent permlinkutopian-io
authorexploringworld
permlinkdevelop-mobile-apps-using-ionic-framework-part-2
titleDevelop Mobile Apps Using Ionic Framework Part-2
body#### Welcome to the Second Video Tutorial of Mobile Apps Development using Ionic Framework <center> <img src= https://imgur.com/hByL8VX.jpg/> </center> #### What Will I Learn? - You will learn how to develop amazing mobile apps using **Ionic Framework** and **Cordova** - You will learn the working of **folder and files** of Ionic Framework - You will learn about **Ionic header, Ionic content and Ionic footer** - Your will learn about **app.js** and **controllers.js** files - Your will learn regarding **ionic classes and ion pain** usage #### Requirements ##### System Requirements: - [Node.js](https://nodejs.org/en/) for building apps - [Visual Studio Code](https://code.visualstudio.com/) for code editing - [Git](https://git-scm.com/downloads) **(Optional)** or Command Prompt or Terminal - An Android or iOS Emulator or mobile device for testing ##### OS Support: - Windows 7/8/10 - macOS - Linux #### Difficulty - Intermediate #### Required Understanding - You just need a little bit of knowledge of HTML,CSS and JS - A fair understanding of Programming - A thirst for learning and developing something new #### Description - This particular video tutorial Series is for everyone who would like to build amazing Android and iOS apps. In this tutorial, you will learn about Ionic Framework with AngularJS from the beginning, that allows you to develop amazing mobile apps with just **HTML, CSS** and **JS**. - All you need is a little bit of understanding of web design . If you are a web developer and want to build mobile apps, Ionic will probably be your piece of cake. You will be able to create amazing apps that will work on both Android and iOS. #### What is Ionic Framework ? Ionic is an HTML5 mobile app development framework targeted at building hybrid mobile apps. Hybrid apps are essentially small websites running in a browser shell in an app that have access to the native platform layer. Hybrid apps have many benefits over pure native apps, specifically in terms of platform support, speed of development, and access to 3rd party code. Think of Ionic as the front-end UI framework that handles all of the look and feel and UI interactions your app needs in order to be compelling. Kind of like **“Bootstrap for Native”** but with support for a broad range of common native mobile components, slick animations, and beautiful design. [Source](https://ionicframework.com/docs/v1/guide/preface.html) #### Some of the key steps that are used in this tutorial *_Below I discuss important coding steps that are must required in this video tutorial_* ##### STEP 1: Now we have learn about how to develop apps using ionic and also how to deploy them on platform. Now we open the `index.html`file In the visual studio code and then at the bottom there is a **body** tag in which there is `<ion-pain>` which contains `<ion-header>` and `<ion-content>` tags, ion-content is basically a container which helps you to organize your content.It allows you to encapsulate your data <center> <img src= https://imgur.com/KS8yvPr.jpg/> </center> ##### STEP 2: Now inside the `<ion-pain>` tag we are going to change the title of our `header` as well as the `class` of our header. To change the color of our header classes provide different types of color combinations for our **headers** So we change the title to **First App** and change the class to `bar-positive`which turns the color of our header to nice blue color. <center> <img src= https://imgur.com/m3jPryB.jpg/> </center> <center> <img src= https://imgur.com/BpkkQrq.jpg/> </center> ##### STEP 3: We can use `<div>` container here as well in place of `<ion-header-bar>`So it will be easier for us to add more functionality easily <center> <img src= https://imgur.com/GgWANt2.jpg/> </center> <center> <img src= https://imgur.com/w8nM9K6.jpg/> </center> ##### STEP 4: Now we can also use `<div>`tag to define footer at the end of the code by using `bar bar-footer bar-calm` tag which defines a cool footer with a blue color at the bottom of our app showing in the emulator and named as **This is the footer** <center> <img src= https://imgur.com/xHK0rgp.jpg/> </center> <center> <img src=https://imgur.com/4GMVCRE.jpg/> </center> _*So our changes in the header and footer classes will look like this*_ <center> <img src= https://imgur.com/x9KEFpY.jpg/> </center> #### Video Tutorial https://youtu.be/VBRHXQbdjDA #### Curriculum This video is second video of the Develop Mobile Apps Using Ionic Framework Series. You can see the first part with the link down below - [Develop Mobile Apps Using Ionic Framework Part-1]( https://utopian.io/utopian-io/@exploringworld/qnj1e-develop-mobile-apps-using-ionic-framework-part-1) <br /><hr/><em>Posted on <a href="https://utopian.io/utopian-io/@exploringworld/develop-mobile-apps-using-ionic-framework-part-2">Utopian.io - Rewarding Open Source Contributors</a></em><hr/>
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":12256376,"name":"ionic","full_name":"ionic-team/ionic","html_url":"https://github.com/ionic-team/ionic","fork":false,"owner":{"login":"ionic-team"}},"pullRequests":[],"platform":"github","type":"video-tutorials","tags":["utopian-io","utopian-io","mobileapps","ionic","tutorial"],"users":["exploringworld"],"links":["https://nodejs.org/en/","https://code.visualstudio.com/","https://git-scm.com/downloads","https://ionicframework.com/docs/v1/guide/preface.html"],"moderator":{"account":"rosatravels","time":"2018-04-28T03:25:12.117Z","pending":false,"reviewed":false,"flagged":true},"questions":null,"score":null,"total_influence":null,"staff_pick":null,"staff_pick_by":null,"config":{"questions":[{"question":"How many substantial concepts does this tutorial address?","question_id":"vtuts-1","answers":[{"answer":"4-5 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-1","value":10},{"answer":"2-3 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-2","value":5},{"answer":"1 substantial concept covered in the tutorial.","answer_id":"vtuts-1-a-3","value":2},{"answer":"More than 5 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-4","value":0}]},{"question":"How informative is the content included alongside the video?","question_id":"vtuts-2","answers":[{"answer":"Exceptionally good text and, when applicable, images for concepts covered.","answer_id":"vtuts-2-a-1","value":10},{"answer":"Thorough text and, if applicable, images for concepts covered.","answer_id":"vtuts-2-a-2","value":5},{"answer":"Minimal text and images.","answer_id":"vtuts-2-a-3","value":3},{"answer":"No or very little text and images.","answer_id":"vtuts-2-a-4","value":0}]},{"question":"Is the video clearly prepared and structured?","question_id":"vtuts-3","answers":[{"answer":"Both the presenter and the video are exceptionally organized, structured and presented","answer_id":"vtuts-3-a-1","value":20},{"answer":"Presenter is prepared and video concepts are structured.","answer_id":"vtuts-3-a-2","value":16},{"answer":"Presenter has moments when he/she seems unprepared and/or the content seems to be unstructured.","answer_id":"vtuts-3-a-3","value":8},{"answer":"Presenter seems unprepared and/or video is unstructured.","answer_id":"vtuts-3-a-4","value":0}]},{"question":"Does the contributor provide supplementary resources, such as code and sample files in the contribution post or a GitHub repository?","question_id":"vtuts-4","answers":[{"answer":"Contributor provided exceptional supplementary resources.","answer_id":"vtuts-4-a-1","value":5},{"answer":"Contributor provided good supplementary resources.","answer_id":"vtuts-4-a-2","value":4},{"answer":"Contributor provided minimal supplementary resources.","answer_id":"vtuts-4-a-3","value":1.5},{"answer":"No supplementary resources were provided.","answer_id":"vtuts-4-a-4","value":0}]},{"question":"How would you describe the sound quality of the video?","question_id":"vtuts-5","answers":[{"answer":"Sound quality is excellent and sounds professionally produced.","answer_id":"vtuts-5-a-1","value":10},{"answer":"The sound is clear and understandable with complimenting background music / sounds.","answer_id":"vtuts-5-a-2","value":7},{"answer":"Low quality of sound and/or mildly distracting background noise.","answer_id":"vtuts-5-a-3","value":3},{"answer":"Distracting background noise and/or very low quality recording.","answer_id":"vtuts-5-a-4","value":0}]},{"question":"Does the presenter speak clearly and is easy to understand?","question_id":"vtuts-6","answers":[{"answer":"Yes, presenter’s speech is highly engaging and professional.","answer_id":"vtuts-6-a-1","value":10},{"answer":"Yes, the voice-over is easy to understand.","answer_id":"vtuts-6-a-2","value":7},{"answer":"Only some of the voice-over was comprehensible.","answer_id":"vtuts-6-a-3","value":2},{"answer":"The voice-over was impossible to understand / not included at all.","answer_id":"vtuts-6-a-4","value":0}]},{"question":"Are the title of the tutorial and the concepts being covered present on the video in text overlay form?","question_id":"vtuts-7","answers":[{"answer":"Title and concepts covered are present in the video at all times in a non-disruptive way.","answer_id":"vtuts-7-a-1","value":5},{"answer":"Title and concepts covered appear temporarily when they are addressed.","answer_id":"vtuts-7-a-2","value":4.5},{"answer":"Only the title is presented and the concepts shown are not addressed in overlay text.","answer_id":"vtuts-7-a-3","value":2},{"answer":"Neither title nor concepts covered are presented in the video text overlay.","answer_id":"vtuts-7-a-4","value":0}]},{"question":"How would you describe the formatting, language and overall presentation of the post?","question_id":"c-1","answers":[{"answer":"The post is of very high quality.","answer_id":"c-1-a-1","value":10},{"answer":"The post is of decent quality, but not spectacular in any way.","answer_id":"c-1-a-2","value":7},{"answer":"The post is poorly written and/or formatted, but readable.","answer_id":"c-1-a-3","value":3},{"answer":"The post is really hard to read and the content is barely understandable.","answer_id":"c-1-a-4","value":0}]},{"question":"How would you rate the overall value of this contribution on the open source community and ecosystem?","question_id":"c-2","answers":[{"answer":"This contribution brings great and impactful value, and can be used for applications outside the specific project.","answer_id":"c-2-a-1","value":20},{"answer":"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.","answer_id":"c-2-a-2","value":16},{"answer":"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.","answer_id":"c-2-a-3","value":8},{"answer":"This contribution adds no value to the open source community and ecosystem or the specific project.","answer_id":"c-2-a-4","value":0}]}]}}
Transaction InfoBlock #21951313/Trx e1b4e607b7505e74ed584b18d168864450ea1749
View Raw JSON Data
{
  "trx_id": "e1b4e607b7505e74ed584b18d168864450ea1749",
  "block": 21951313,
  "trx_in_block": 35,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-28T03:25:12",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "develop-mobile-apps-using-ionic-framework-part-2",
      "title": "Develop Mobile Apps Using Ionic Framework Part-2",
      "body": "#### Welcome to the Second Video Tutorial of Mobile Apps Development using Ionic Framework\n<center> <img src= https://imgur.com/hByL8VX.jpg/> </center>\n\n#### What Will I Learn?\n\n- You will learn how to develop amazing mobile apps using **Ionic Framework** and **Cordova**\n- You will learn the working of **folder and files** of Ionic Framework\n- You will learn about **Ionic header, Ionic content and Ionic footer**\n- Your will learn about **app.js** and **controllers.js** files\n- Your will learn regarding **ionic classes and ion pain** usage\n\n\n\n#### Requirements\n##### System Requirements:\n\n- [Node.js](https://nodejs.org/en/) for building apps\n- [Visual Studio Code](https://code.visualstudio.com/) for code editing \n- [Git](https://git-scm.com/downloads) **(Optional)** or Command Prompt or Terminal\n- An Android or iOS Emulator or mobile device for testing\n##### OS Support:\n\n- Windows 7/8/10\n- macOS \n- Linux \n#### Difficulty\n\n\n\n- Intermediate\n\n#### Required Understanding\n- You just need a little bit of knowledge of HTML,CSS and JS\n- A fair understanding of Programming \n- A thirst for learning and developing something new\n\n\n#### Description\n-\tThis particular video tutorial Series is for everyone who would like to build amazing Android and iOS apps. In this tutorial, you will learn about Ionic Framework with AngularJS from the beginning, that allows you to develop amazing mobile apps with just **HTML, CSS** and **JS**.\n-\tAll you need is a little bit of understanding of web design\t . If you are a web developer and want to build mobile apps, Ionic will probably be your piece of cake. You will be able to create amazing apps that will work on both Android and iOS.\n#### What is Ionic Framework ?\nIonic is an HTML5 mobile app development framework targeted at building hybrid mobile apps. Hybrid apps are essentially small websites running in a browser shell in an app that have access to the native platform layer. Hybrid apps have many benefits over pure native apps, specifically in terms of platform support, speed of development, and access to 3rd party code.\nThink of Ionic as the front-end UI framework that handles all of the look and feel and UI interactions your app needs in order to be compelling. Kind of like **“Bootstrap for Native”** but with support for a broad range of common native mobile components, slick animations, and beautiful design. [Source](https://ionicframework.com/docs/v1/guide/preface.html)\n#### Some of the key steps that are used in this tutorial\n*_Below I discuss important coding steps that are must required in this video tutorial_*\n##### STEP 1:\nNow we have learn about how to develop apps using ionic and also \nhow to deploy them on platform. Now we open the `index.html`file \nIn the visual studio code and then at the bottom there is a **body**\ntag in which there is `<ion-pain>` which contains `<ion-header>` and `<ion-content>` tags, ion-content is basically a container which helps you to organize your content.It allows you to encapsulate your data\n<center> <img src= https://imgur.com/KS8yvPr.jpg/> </center>\n\n##### STEP 2:\nNow inside the `<ion-pain>` tag we are going to change the title of our `header` as well as the `class` of our header. To change the color of our header classes provide different types of color combinations for our **headers**\nSo we change the title to **First App** and change the class to `bar-positive`which turns the color of our header to nice blue color.\n<center> <img src= https://imgur.com/m3jPryB.jpg/> </center>\n\n\n<center> <img src= https://imgur.com/BpkkQrq.jpg/> </center>\n\n##### STEP 3:\nWe can use  `<div>` container here as well in place of `<ion-header-bar>`So it will be easier for us to add more functionality easily\n<center> <img src= https://imgur.com/GgWANt2.jpg/> </center>\n\n\n<center> <img src= https://imgur.com/w8nM9K6.jpg/> </center>\n\n##### STEP 4:\nNow we can also use `<div>`tag to define footer at the end of the code by using `bar bar-footer bar-calm` tag which defines a cool footer with a blue color at the bottom of our app showing in the emulator and named as **This is the footer**\n<center> <img src= https://imgur.com/xHK0rgp.jpg/> </center>\n\n\n<center> <img src=https://imgur.com/4GMVCRE.jpg/> </center>\n\n_*So our changes in the header and footer classes will look like this*_\n<center> <img src= https://imgur.com/x9KEFpY.jpg/> </center>\n\n\n#### Video Tutorial\nhttps://youtu.be/VBRHXQbdjDA\n#### Curriculum\nThis video is second video of the Develop Mobile Apps Using Ionic Framework Series. You can see the first part with the link down below\n- [Develop Mobile Apps Using Ionic Framework Part-1]( https://utopian.io/utopian-io/@exploringworld/qnj1e-develop-mobile-apps-using-ionic-framework-part-1) \n\n\n\n<br /><hr/><em>Posted on <a href=\"https://utopian.io/utopian-io/@exploringworld/develop-mobile-apps-using-ionic-framework-part-2\">Utopian.io -  Rewarding Open Source Contributors</a></em><hr/>",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":12256376,\"name\":\"ionic\",\"full_name\":\"ionic-team/ionic\",\"html_url\":\"https://github.com/ionic-team/ionic\",\"fork\":false,\"owner\":{\"login\":\"ionic-team\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"video-tutorials\",\"tags\":[\"utopian-io\",\"utopian-io\",\"mobileapps\",\"ionic\",\"tutorial\"],\"users\":[\"exploringworld\"],\"links\":[\"https://nodejs.org/en/\",\"https://code.visualstudio.com/\",\"https://git-scm.com/downloads\",\"https://ionicframework.com/docs/v1/guide/preface.html\"],\"moderator\":{\"account\":\"rosatravels\",\"time\":\"2018-04-28T03:25:12.117Z\",\"pending\":false,\"reviewed\":false,\"flagged\":true},\"questions\":null,\"score\":null,\"total_influence\":null,\"staff_pick\":null,\"staff_pick_by\":null,\"config\":{\"questions\":[{\"question\":\"How many substantial concepts does this tutorial address?\",\"question_id\":\"vtuts-1\",\"answers\":[{\"answer\":\"4-5 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-1\",\"value\":10},{\"answer\":\"2-3 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-2\",\"value\":5},{\"answer\":\"1 substantial concept covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-3\",\"value\":2},{\"answer\":\"More than 5 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-4\",\"value\":0}]},{\"question\":\"How informative is the content included alongside the video?\",\"question_id\":\"vtuts-2\",\"answers\":[{\"answer\":\"Exceptionally good text and, when applicable, images for concepts covered.\",\"answer_id\":\"vtuts-2-a-1\",\"value\":10},{\"answer\":\"Thorough text and, if applicable, images for concepts covered.\",\"answer_id\":\"vtuts-2-a-2\",\"value\":5},{\"answer\":\"Minimal text and images.\",\"answer_id\":\"vtuts-2-a-3\",\"value\":3},{\"answer\":\"No or very little text and images.\",\"answer_id\":\"vtuts-2-a-4\",\"value\":0}]},{\"question\":\"Is the video clearly prepared and structured?\",\"question_id\":\"vtuts-3\",\"answers\":[{\"answer\":\"Both the presenter and the video are exceptionally organized, structured and presented\",\"answer_id\":\"vtuts-3-a-1\",\"value\":20},{\"answer\":\"Presenter is prepared and video concepts are structured.\",\"answer_id\":\"vtuts-3-a-2\",\"value\":16},{\"answer\":\"Presenter has moments when he/she seems unprepared and/or the content seems to be unstructured.\",\"answer_id\":\"vtuts-3-a-3\",\"value\":8},{\"answer\":\"Presenter seems unprepared and/or video is unstructured.\",\"answer_id\":\"vtuts-3-a-4\",\"value\":0}]},{\"question\":\"Does the contributor provide supplementary resources, such as code and sample files in the contribution post or a GitHub repository?\",\"question_id\":\"vtuts-4\",\"answers\":[{\"answer\":\"Contributor provided exceptional supplementary resources.\",\"answer_id\":\"vtuts-4-a-1\",\"value\":5},{\"answer\":\"Contributor provided good supplementary resources.\",\"answer_id\":\"vtuts-4-a-2\",\"value\":4},{\"answer\":\"Contributor provided minimal supplementary resources.\",\"answer_id\":\"vtuts-4-a-3\",\"value\":1.5},{\"answer\":\"No supplementary resources were provided.\",\"answer_id\":\"vtuts-4-a-4\",\"value\":0}]},{\"question\":\"How would you describe the sound quality of the video?\",\"question_id\":\"vtuts-5\",\"answers\":[{\"answer\":\"Sound quality is excellent and sounds professionally produced.\",\"answer_id\":\"vtuts-5-a-1\",\"value\":10},{\"answer\":\"The sound is clear and understandable with complimenting background music / sounds.\",\"answer_id\":\"vtuts-5-a-2\",\"value\":7},{\"answer\":\"Low quality of sound and/or mildly distracting background noise.\",\"answer_id\":\"vtuts-5-a-3\",\"value\":3},{\"answer\":\"Distracting background noise and/or very low quality recording.\",\"answer_id\":\"vtuts-5-a-4\",\"value\":0}]},{\"question\":\"Does the presenter speak clearly and is easy to understand?\",\"question_id\":\"vtuts-6\",\"answers\":[{\"answer\":\"Yes, presenter’s speech is highly engaging and professional.\",\"answer_id\":\"vtuts-6-a-1\",\"value\":10},{\"answer\":\"Yes, the voice-over is easy to understand.\",\"answer_id\":\"vtuts-6-a-2\",\"value\":7},{\"answer\":\"Only some of the voice-over was comprehensible.\",\"answer_id\":\"vtuts-6-a-3\",\"value\":2},{\"answer\":\"The voice-over was impossible to understand / not included at all.\",\"answer_id\":\"vtuts-6-a-4\",\"value\":0}]},{\"question\":\"Are the title of the tutorial and the concepts being covered present on the video in text overlay form?\",\"question_id\":\"vtuts-7\",\"answers\":[{\"answer\":\"Title and concepts covered are present in the video at all times in a non-disruptive way.\",\"answer_id\":\"vtuts-7-a-1\",\"value\":5},{\"answer\":\"Title and concepts covered appear temporarily when they are addressed.\",\"answer_id\":\"vtuts-7-a-2\",\"value\":4.5},{\"answer\":\"Only the title is presented and the concepts shown are not addressed in overlay text.\",\"answer_id\":\"vtuts-7-a-3\",\"value\":2},{\"answer\":\"Neither title nor concepts covered are presented in the video text overlay.\",\"answer_id\":\"vtuts-7-a-4\",\"value\":0}]},{\"question\":\"How would you describe the formatting, language and overall presentation of the post?\",\"question_id\":\"c-1\",\"answers\":[{\"answer\":\"The post is of very high quality.\",\"answer_id\":\"c-1-a-1\",\"value\":10},{\"answer\":\"The post is of decent quality, but not spectacular in any way.\",\"answer_id\":\"c-1-a-2\",\"value\":7},{\"answer\":\"The post is poorly written and/or formatted, but readable.\",\"answer_id\":\"c-1-a-3\",\"value\":3},{\"answer\":\"The post is really hard to read and the content is barely understandable.\",\"answer_id\":\"c-1-a-4\",\"value\":0}]},{\"question\":\"How would you rate the overall value of this contribution on the open source community and ecosystem?\",\"question_id\":\"c-2\",\"answers\":[{\"answer\":\"This contribution brings great and impactful value, and can be used for applications outside the specific project.\",\"answer_id\":\"c-2-a-1\",\"value\":20},{\"answer\":\"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.\",\"answer_id\":\"c-2-a-2\",\"value\":16},{\"answer\":\"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.\",\"answer_id\":\"c-2-a-3\",\"value\":8},{\"answer\":\"This contribution adds no value to the open source community and ecosystem or the specific project.\",\"answer_id\":\"c-2-a-4\",\"value\":0}]}]}}"
    }
  ]
}
2018/04/28 03:24:54
parent author
parent permlinkutopian-io
authorexploringworld
permlinkdevelop-mobile-apps-using-ionic-framework-part-2
titleDevelop Mobile Apps Using Ionic Framework Part-2
body#### Welcome to the Second Video Tutorial of Mobile Apps Development using Ionic Framework <center> <img src= https://imgur.com/hByL8VX.jpg/> </center> #### What Will I Learn? - You will learn how to develop amazing mobile apps using **Ionic Framework** and **Cordova** - You will learn the working of **folder and files** of Ionic Framework - You will learn about **Ionic header, Ionic content and Ionic footer** - Your will learn about **app.js** and **controllers.js** files - Your will learn regarding **ionic classes and ion pain** usage #### Requirements ##### System Requirements: - [Node.js](https://nodejs.org/en/) for building apps - [Visual Studio Code](https://code.visualstudio.com/) for code editing - [Git](https://git-scm.com/downloads) **(Optional)** or Command Prompt or Terminal - An Android or iOS Emulator or mobile device for testing ##### OS Support: - Windows 7/8/10 - macOS - Linux #### Difficulty - Intermediate #### Required Understanding - You just need a little bit of knowledge of HTML,CSS and JS - A fair understanding of Programming - A thirst for learning and developing something new #### Description - This particular video tutorial Series is for everyone who would like to build amazing Android and iOS apps. In this tutorial, you will learn about Ionic Framework with AngularJS from the beginning, that allows you to develop amazing mobile apps with just **HTML, CSS** and **JS**. - All you need is a little bit of understanding of web design . If you are a web developer and want to build mobile apps, Ionic will probably be your piece of cake. You will be able to create amazing apps that will work on both Android and iOS. #### What is Ionic Framework ? Ionic is an HTML5 mobile app development framework targeted at building hybrid mobile apps. Hybrid apps are essentially small websites running in a browser shell in an app that have access to the native platform layer. Hybrid apps have many benefits over pure native apps, specifically in terms of platform support, speed of development, and access to 3rd party code. Think of Ionic as the front-end UI framework that handles all of the look and feel and UI interactions your app needs in order to be compelling. Kind of like **“Bootstrap for Native”** but with support for a broad range of common native mobile components, slick animations, and beautiful design. [Source](https://ionicframework.com/docs/v1/guide/preface.html) #### Some of the key steps that are used in this tutorial *_Below I discuss important coding steps that are must required in this video tutorial_* ##### STEP 1: Now we have learn about how to develop apps using ionic and also how to deploy them on platform. Now we open the `index.html`file In the visual studio code and then at the bottom there is a **body** tag in which there is `<ion-pain>` which contains `<ion-header>` and `<ion-content>` tags, ion-content is basically a container which helps you to organize your content.It allows you to encapsulate your data <center> <img src= https://imgur.com/KS8yvPr.jpg/> </center> ##### STEP 2: Now inside the `<ion-pain>` tag we are going to change the title of our `header` as well as the `class` of our header. To change the color of our header classes provide different types of color combinations for our **headers** So we change the title to **First App** and change the class to `bar-positive`which turns the color of our header to nice blue color. <center> <img src= https://imgur.com/m3jPryB.jpg/> </center> <center> <img src= https://imgur.com/BpkkQrq.jpg/> </center> ##### STEP 3: We can use `<div>` container here as well in place of `<ion-header-bar>`So it will be easier for us to add more functionality easily <center> <img src= https://imgur.com/GgWANt2.jpg/> </center> <center> <img src= https://imgur.com/w8nM9K6.jpg/> </center> ##### STEP 4: Now we can also use `<div>`tag to define footer at the end of the code by using `bar bar-footer bar-calm` tag which defines a cool footer with a blue color at the bottom of our app showing in the emulator and named as **This is the footer** <center> <img src= https://imgur.com/xHK0rgp.jpg/> </center> <center> <img src=https://imgur.com/4GMVCRE.jpg/> </center> _*So our changes in the header and footer classes will look like this*_ <center> <img src= https://imgur.com/x9KEFpY.jpg/> </center> #### Video Tutorial https://youtu.be/VBRHXQbdjDA #### Curriculum This video is second video of the Develop Mobile Apps Using Ionic Framework Series. You can see the first part with the link down below - [Develop Mobile Apps Using Ionic Framework Part-1]( https://utopian.io/utopian-io/@exploringworld/qnj1e-develop-mobile-apps-using-ionic-framework-part-1) <br /><hr/><em>Posted on <a href="https://utopian.io/utopian-io/@exploringworld/develop-mobile-apps-using-ionic-framework-part-2">Utopian.io - Rewarding Open Source Contributors</a></em><hr/>
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":12256376,"name":"ionic","full_name":"ionic-team/ionic","html_url":"https://github.com/ionic-team/ionic","fork":false,"owner":{"login":"ionic-team"}},"pullRequests":[],"platform":"github","type":"video-tutorials","tags":["utopian-io","utopian-io","mobileapps","ionic","tutorial"],"users":["exploringworld"],"links":["https://nodejs.org/en/","https://code.visualstudio.com/","https://git-scm.com/downloads","https://ionicframework.com/docs/v1/guide/preface.html"],"moderator":{"account":"rosatravels","time":"2018-04-28T03:24:52.205Z","pending":false,"reviewed":false,"flagged":true},"questions":null,"score":null,"total_influence":null,"staff_pick":null,"staff_pick_by":null,"config":{"questions":[{"question":"How many substantial concepts does this tutorial address?","question_id":"vtuts-1","answers":[{"answer":"4-5 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-1","value":10},{"answer":"2-3 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-2","value":5},{"answer":"1 substantial concept covered in the tutorial.","answer_id":"vtuts-1-a-3","value":2},{"answer":"More than 5 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-4","value":0}]},{"question":"How informative is the content included alongside the video?","question_id":"vtuts-2","answers":[{"answer":"Exceptionally good text and, when applicable, images for concepts covered.","answer_id":"vtuts-2-a-1","value":10},{"answer":"Thorough text and, if applicable, images for concepts covered.","answer_id":"vtuts-2-a-2","value":5},{"answer":"Minimal text and images.","answer_id":"vtuts-2-a-3","value":3},{"answer":"No or very little text and images.","answer_id":"vtuts-2-a-4","value":0}]},{"question":"Is the video clearly prepared and structured?","question_id":"vtuts-3","answers":[{"answer":"Both the presenter and the video are exceptionally organized, structured and presented","answer_id":"vtuts-3-a-1","value":20},{"answer":"Presenter is prepared and video concepts are structured.","answer_id":"vtuts-3-a-2","value":16},{"answer":"Presenter has moments when he/she seems unprepared and/or the content seems to be unstructured.","answer_id":"vtuts-3-a-3","value":8},{"answer":"Presenter seems unprepared and/or video is unstructured.","answer_id":"vtuts-3-a-4","value":0}]},{"question":"Does the contributor provide supplementary resources, such as code and sample files in the contribution post or a GitHub repository?","question_id":"vtuts-4","answers":[{"answer":"Contributor provided exceptional supplementary resources.","answer_id":"vtuts-4-a-1","value":5},{"answer":"Contributor provided good supplementary resources.","answer_id":"vtuts-4-a-2","value":4},{"answer":"Contributor provided minimal supplementary resources.","answer_id":"vtuts-4-a-3","value":1.5},{"answer":"No supplementary resources were provided.","answer_id":"vtuts-4-a-4","value":0}]},{"question":"How would you describe the sound quality of the video?","question_id":"vtuts-5","answers":[{"answer":"Sound quality is excellent and sounds professionally produced.","answer_id":"vtuts-5-a-1","value":10},{"answer":"The sound is clear and understandable with complimenting background music / sounds.","answer_id":"vtuts-5-a-2","value":7},{"answer":"Low quality of sound and/or mildly distracting background noise.","answer_id":"vtuts-5-a-3","value":3},{"answer":"Distracting background noise and/or very low quality recording.","answer_id":"vtuts-5-a-4","value":0}]},{"question":"Does the presenter speak clearly and is easy to understand?","question_id":"vtuts-6","answers":[{"answer":"Yes, presenter’s speech is highly engaging and professional.","answer_id":"vtuts-6-a-1","value":10},{"answer":"Yes, the voice-over is easy to understand.","answer_id":"vtuts-6-a-2","value":7},{"answer":"Only some of the voice-over was comprehensible.","answer_id":"vtuts-6-a-3","value":2},{"answer":"The voice-over was impossible to understand / not included at all.","answer_id":"vtuts-6-a-4","value":0}]},{"question":"Are the title of the tutorial and the concepts being covered present on the video in text overlay form?","question_id":"vtuts-7","answers":[{"answer":"Title and concepts covered are present in the video at all times in a non-disruptive way.","answer_id":"vtuts-7-a-1","value":5},{"answer":"Title and concepts covered appear temporarily when they are addressed.","answer_id":"vtuts-7-a-2","value":4.5},{"answer":"Only the title is presented and the concepts shown are not addressed in overlay text.","answer_id":"vtuts-7-a-3","value":2},{"answer":"Neither title nor concepts covered are presented in the video text overlay.","answer_id":"vtuts-7-a-4","value":0}]},{"question":"How would you describe the formatting, language and overall presentation of the post?","question_id":"c-1","answers":[{"answer":"The post is of very high quality.","answer_id":"c-1-a-1","value":10},{"answer":"The post is of decent quality, but not spectacular in any way.","answer_id":"c-1-a-2","value":7},{"answer":"The post is poorly written and/or formatted, but readable.","answer_id":"c-1-a-3","value":3},{"answer":"The post is really hard to read and the content is barely understandable.","answer_id":"c-1-a-4","value":0}]},{"question":"How would you rate the overall value of this contribution on the open source community and ecosystem?","question_id":"c-2","answers":[{"answer":"This contribution brings great and impactful value, and can be used for applications outside the specific project.","answer_id":"c-2-a-1","value":20},{"answer":"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.","answer_id":"c-2-a-2","value":16},{"answer":"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.","answer_id":"c-2-a-3","value":8},{"answer":"This contribution adds no value to the open source community and ecosystem or the specific project.","answer_id":"c-2-a-4","value":0}]}]}}
Transaction InfoBlock #21951307/Trx a1849d56d4ebaae9daa96521c0dbd76ab7a02043
View Raw JSON Data
{
  "trx_id": "a1849d56d4ebaae9daa96521c0dbd76ab7a02043",
  "block": 21951307,
  "trx_in_block": 2,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-28T03:24:54",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "develop-mobile-apps-using-ionic-framework-part-2",
      "title": "Develop Mobile Apps Using Ionic Framework Part-2",
      "body": "#### Welcome to the Second Video Tutorial of Mobile Apps Development using Ionic Framework\n<center> <img src= https://imgur.com/hByL8VX.jpg/> </center>\n\n#### What Will I Learn?\n\n- You will learn how to develop amazing mobile apps using **Ionic Framework** and **Cordova**\n- You will learn the working of **folder and files** of Ionic Framework\n- You will learn about **Ionic header, Ionic content and Ionic footer**\n- Your will learn about **app.js** and **controllers.js** files\n- Your will learn regarding **ionic classes and ion pain** usage\n\n\n\n#### Requirements\n##### System Requirements:\n\n- [Node.js](https://nodejs.org/en/) for building apps\n- [Visual Studio Code](https://code.visualstudio.com/) for code editing \n- [Git](https://git-scm.com/downloads) **(Optional)** or Command Prompt or Terminal\n- An Android or iOS Emulator or mobile device for testing\n##### OS Support:\n\n- Windows 7/8/10\n- macOS \n- Linux \n#### Difficulty\n\n\n\n- Intermediate\n\n#### Required Understanding\n- You just need a little bit of knowledge of HTML,CSS and JS\n- A fair understanding of Programming \n- A thirst for learning and developing something new\n\n\n#### Description\n-\tThis particular video tutorial Series is for everyone who would like to build amazing Android and iOS apps. In this tutorial, you will learn about Ionic Framework with AngularJS from the beginning, that allows you to develop amazing mobile apps with just **HTML, CSS** and **JS**.\n-\tAll you need is a little bit of understanding of web design\t . If you are a web developer and want to build mobile apps, Ionic will probably be your piece of cake. You will be able to create amazing apps that will work on both Android and iOS.\n#### What is Ionic Framework ?\nIonic is an HTML5 mobile app development framework targeted at building hybrid mobile apps. Hybrid apps are essentially small websites running in a browser shell in an app that have access to the native platform layer. Hybrid apps have many benefits over pure native apps, specifically in terms of platform support, speed of development, and access to 3rd party code.\nThink of Ionic as the front-end UI framework that handles all of the look and feel and UI interactions your app needs in order to be compelling. Kind of like **“Bootstrap for Native”** but with support for a broad range of common native mobile components, slick animations, and beautiful design. [Source](https://ionicframework.com/docs/v1/guide/preface.html)\n#### Some of the key steps that are used in this tutorial\n*_Below I discuss important coding steps that are must required in this video tutorial_*\n##### STEP 1:\nNow we have learn about how to develop apps using ionic and also \nhow to deploy them on platform. Now we open the `index.html`file \nIn the visual studio code and then at the bottom there is a **body**\ntag in which there is `<ion-pain>` which contains `<ion-header>` and `<ion-content>` tags, ion-content is basically a container which helps you to organize your content.It allows you to encapsulate your data\n<center> <img src= https://imgur.com/KS8yvPr.jpg/> </center>\n\n##### STEP 2:\nNow inside the `<ion-pain>` tag we are going to change the title of our `header` as well as the `class` of our header. To change the color of our header classes provide different types of color combinations for our **headers**\nSo we change the title to **First App** and change the class to `bar-positive`which turns the color of our header to nice blue color.\n<center> <img src= https://imgur.com/m3jPryB.jpg/> </center>\n\n\n<center> <img src= https://imgur.com/BpkkQrq.jpg/> </center>\n\n##### STEP 3:\nWe can use  `<div>` container here as well in place of `<ion-header-bar>`So it will be easier for us to add more functionality easily\n<center> <img src= https://imgur.com/GgWANt2.jpg/> </center>\n\n\n<center> <img src= https://imgur.com/w8nM9K6.jpg/> </center>\n\n##### STEP 4:\nNow we can also use `<div>`tag to define footer at the end of the code by using `bar bar-footer bar-calm` tag which defines a cool footer with a blue color at the bottom of our app showing in the emulator and named as **This is the footer**\n<center> <img src= https://imgur.com/xHK0rgp.jpg/> </center>\n\n\n<center> <img src=https://imgur.com/4GMVCRE.jpg/> </center>\n\n_*So our changes in the header and footer classes will look like this*_\n<center> <img src= https://imgur.com/x9KEFpY.jpg/> </center>\n\n\n#### Video Tutorial\nhttps://youtu.be/VBRHXQbdjDA\n#### Curriculum\nThis video is second video of the Develop Mobile Apps Using Ionic Framework Series. You can see the first part with the link down below\n- [Develop Mobile Apps Using Ionic Framework Part-1]( https://utopian.io/utopian-io/@exploringworld/qnj1e-develop-mobile-apps-using-ionic-framework-part-1) \n\n\n\n<br /><hr/><em>Posted on <a href=\"https://utopian.io/utopian-io/@exploringworld/develop-mobile-apps-using-ionic-framework-part-2\">Utopian.io -  Rewarding Open Source Contributors</a></em><hr/>",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":12256376,\"name\":\"ionic\",\"full_name\":\"ionic-team/ionic\",\"html_url\":\"https://github.com/ionic-team/ionic\",\"fork\":false,\"owner\":{\"login\":\"ionic-team\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"video-tutorials\",\"tags\":[\"utopian-io\",\"utopian-io\",\"mobileapps\",\"ionic\",\"tutorial\"],\"users\":[\"exploringworld\"],\"links\":[\"https://nodejs.org/en/\",\"https://code.visualstudio.com/\",\"https://git-scm.com/downloads\",\"https://ionicframework.com/docs/v1/guide/preface.html\"],\"moderator\":{\"account\":\"rosatravels\",\"time\":\"2018-04-28T03:24:52.205Z\",\"pending\":false,\"reviewed\":false,\"flagged\":true},\"questions\":null,\"score\":null,\"total_influence\":null,\"staff_pick\":null,\"staff_pick_by\":null,\"config\":{\"questions\":[{\"question\":\"How many substantial concepts does this tutorial address?\",\"question_id\":\"vtuts-1\",\"answers\":[{\"answer\":\"4-5 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-1\",\"value\":10},{\"answer\":\"2-3 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-2\",\"value\":5},{\"answer\":\"1 substantial concept covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-3\",\"value\":2},{\"answer\":\"More than 5 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-4\",\"value\":0}]},{\"question\":\"How informative is the content included alongside the video?\",\"question_id\":\"vtuts-2\",\"answers\":[{\"answer\":\"Exceptionally good text and, when applicable, images for concepts covered.\",\"answer_id\":\"vtuts-2-a-1\",\"value\":10},{\"answer\":\"Thorough text and, if applicable, images for concepts covered.\",\"answer_id\":\"vtuts-2-a-2\",\"value\":5},{\"answer\":\"Minimal text and images.\",\"answer_id\":\"vtuts-2-a-3\",\"value\":3},{\"answer\":\"No or very little text and images.\",\"answer_id\":\"vtuts-2-a-4\",\"value\":0}]},{\"question\":\"Is the video clearly prepared and structured?\",\"question_id\":\"vtuts-3\",\"answers\":[{\"answer\":\"Both the presenter and the video are exceptionally organized, structured and presented\",\"answer_id\":\"vtuts-3-a-1\",\"value\":20},{\"answer\":\"Presenter is prepared and video concepts are structured.\",\"answer_id\":\"vtuts-3-a-2\",\"value\":16},{\"answer\":\"Presenter has moments when he/she seems unprepared and/or the content seems to be unstructured.\",\"answer_id\":\"vtuts-3-a-3\",\"value\":8},{\"answer\":\"Presenter seems unprepared and/or video is unstructured.\",\"answer_id\":\"vtuts-3-a-4\",\"value\":0}]},{\"question\":\"Does the contributor provide supplementary resources, such as code and sample files in the contribution post or a GitHub repository?\",\"question_id\":\"vtuts-4\",\"answers\":[{\"answer\":\"Contributor provided exceptional supplementary resources.\",\"answer_id\":\"vtuts-4-a-1\",\"value\":5},{\"answer\":\"Contributor provided good supplementary resources.\",\"answer_id\":\"vtuts-4-a-2\",\"value\":4},{\"answer\":\"Contributor provided minimal supplementary resources.\",\"answer_id\":\"vtuts-4-a-3\",\"value\":1.5},{\"answer\":\"No supplementary resources were provided.\",\"answer_id\":\"vtuts-4-a-4\",\"value\":0}]},{\"question\":\"How would you describe the sound quality of the video?\",\"question_id\":\"vtuts-5\",\"answers\":[{\"answer\":\"Sound quality is excellent and sounds professionally produced.\",\"answer_id\":\"vtuts-5-a-1\",\"value\":10},{\"answer\":\"The sound is clear and understandable with complimenting background music / sounds.\",\"answer_id\":\"vtuts-5-a-2\",\"value\":7},{\"answer\":\"Low quality of sound and/or mildly distracting background noise.\",\"answer_id\":\"vtuts-5-a-3\",\"value\":3},{\"answer\":\"Distracting background noise and/or very low quality recording.\",\"answer_id\":\"vtuts-5-a-4\",\"value\":0}]},{\"question\":\"Does the presenter speak clearly and is easy to understand?\",\"question_id\":\"vtuts-6\",\"answers\":[{\"answer\":\"Yes, presenter’s speech is highly engaging and professional.\",\"answer_id\":\"vtuts-6-a-1\",\"value\":10},{\"answer\":\"Yes, the voice-over is easy to understand.\",\"answer_id\":\"vtuts-6-a-2\",\"value\":7},{\"answer\":\"Only some of the voice-over was comprehensible.\",\"answer_id\":\"vtuts-6-a-3\",\"value\":2},{\"answer\":\"The voice-over was impossible to understand / not included at all.\",\"answer_id\":\"vtuts-6-a-4\",\"value\":0}]},{\"question\":\"Are the title of the tutorial and the concepts being covered present on the video in text overlay form?\",\"question_id\":\"vtuts-7\",\"answers\":[{\"answer\":\"Title and concepts covered are present in the video at all times in a non-disruptive way.\",\"answer_id\":\"vtuts-7-a-1\",\"value\":5},{\"answer\":\"Title and concepts covered appear temporarily when they are addressed.\",\"answer_id\":\"vtuts-7-a-2\",\"value\":4.5},{\"answer\":\"Only the title is presented and the concepts shown are not addressed in overlay text.\",\"answer_id\":\"vtuts-7-a-3\",\"value\":2},{\"answer\":\"Neither title nor concepts covered are presented in the video text overlay.\",\"answer_id\":\"vtuts-7-a-4\",\"value\":0}]},{\"question\":\"How would you describe the formatting, language and overall presentation of the post?\",\"question_id\":\"c-1\",\"answers\":[{\"answer\":\"The post is of very high quality.\",\"answer_id\":\"c-1-a-1\",\"value\":10},{\"answer\":\"The post is of decent quality, but not spectacular in any way.\",\"answer_id\":\"c-1-a-2\",\"value\":7},{\"answer\":\"The post is poorly written and/or formatted, but readable.\",\"answer_id\":\"c-1-a-3\",\"value\":3},{\"answer\":\"The post is really hard to read and the content is barely understandable.\",\"answer_id\":\"c-1-a-4\",\"value\":0}]},{\"question\":\"How would you rate the overall value of this contribution on the open source community and ecosystem?\",\"question_id\":\"c-2\",\"answers\":[{\"answer\":\"This contribution brings great and impactful value, and can be used for applications outside the specific project.\",\"answer_id\":\"c-2-a-1\",\"value\":20},{\"answer\":\"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.\",\"answer_id\":\"c-2-a-2\",\"value\":16},{\"answer\":\"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.\",\"answer_id\":\"c-2-a-3\",\"value\":8},{\"answer\":\"This contribution adds no value to the open source community and ecosystem or the specific project.\",\"answer_id\":\"c-2-a-4\",\"value\":0}]}]}}"
    }
  ]
}
2018/04/28 03:06:00
parent author
parent permlinkutopian-io
authorexploringworld
permlinkdevelop-mobile-apps-using-ionic-framework-part-2
titleDevelop Mobile Apps Using Ionic Framework Part-2
body#### Welcome to the Second Video Tutorial of Mobile Apps Development using Ionic Framework <center> <img src= https://imgur.com/hByL8VX.jpg/> </center> #### What Will I Learn? - You will learn how to develop amazing mobile apps using **Ionic Framework** and **Cordova** - You will learn the working of **folder and files** of Ionic Framework - You will learn about **Ionic header, Ionic content and Ionic footer** - Your will learn about **app.js** and **controllers.js** files - Your will learn regarding **ionic classes and ion pain** usage #### Requirements ##### System Requirements: - [Node.js](https://nodejs.org/en/) for building apps - [Visual Studio Code](https://code.visualstudio.com/) for code editing - [Git](https://git-scm.com/downloads) **(Optional)** or Command Prompt or Terminal - An Android or iOS Emulator or mobile device for testing ##### OS Support: - Windows 7/8/10 - macOS - Linux #### Difficulty - Intermediate #### Required Understanding - You just need a little bit of knowledge of HTML,CSS and JS - A fair understanding of Programming - A thirst for learning and developing something new #### Description - This particular video tutorial Series is for everyone who would like to build amazing Android and iOS apps. In this tutorial, you will learn about Ionic Framework with AngularJS from the beginning, that allows you to develop amazing mobile apps with just **HTML, CSS** and **JS**. - All you need is a little bit of understanding of web design . If you are a web developer and want to build mobile apps, Ionic will probably be your piece of cake. You will be able to create amazing apps that will work on both Android and iOS. #### What is Ionic Framework ? Ionic is an HTML5 mobile app development framework targeted at building hybrid mobile apps. Hybrid apps are essentially small websites running in a browser shell in an app that have access to the native platform layer. Hybrid apps have many benefits over pure native apps, specifically in terms of platform support, speed of development, and access to 3rd party code. Think of Ionic as the front-end UI framework that handles all of the look and feel and UI interactions your app needs in order to be compelling. Kind of like **“Bootstrap for Native”** but with support for a broad range of common native mobile components, slick animations, and beautiful design. [Source](https://ionicframework.com/docs/v1/guide/preface.html) #### Some of the key steps that are used in this tutorial *_Below I discuss important coding steps that are must required in this video tutorial_* ##### STEP 1: Now we have learn about how to develop apps using ionic and also how to deploy them on platform. Now we open the `index.html`file In the visual studio code and then at the bottom there is a **body** tag in which there is `<ion-pain>` which contains `<ion-header>` and `<ion-content>` tags, ion-content is basically a container which helps you to organize your content.It allows you to encapsulate your data <center> <img src= https://imgur.com/KS8yvPr.jpg/> </center> ##### STEP 2: Now inside the `<ion-pain>` tag we are going to change the title of our `header` as well as the `class` of our header. To change the color of our header classes provide different types of color combinations for our **headers** So we change the title to **First App** and change the class to `bar-positive`which turns the color of our header to nice blue color. <center> <img src= https://imgur.com/m3jPryB.jpg/> </center> <center> <img src= https://imgur.com/BpkkQrq.jpg/> </center> ##### STEP 3: We can use `<div>` container here as well in place of `<ion-header-bar>`So it will be easier for us to add more functionality easily <center> <img src= https://imgur.com/GgWANt2.jpg/> </center> <center> <img src= https://imgur.com/w8nM9K6.jpg/> </center> ##### STEP 4: Now we can also use `<div>`tag to define footer at the end of the code by using `bar bar-footer bar-calm` tag which defines a cool footer with a blue color at the bottom of our app showing in the emulator and named as **This is the footer** <center> <img src= https://imgur.com/xHK0rgp.jpg/> </center> <center> <img src=https://imgur.com/4GMVCRE.jpg/> </center> _*So our changes in the header and footer classes will look like this*_ <center> <img src= https://imgur.com/x9KEFpY.jpg/> </center> #### Video Tutorial https://youtu.be/VBRHXQbdjDA #### Curriculum This video is second video of the Develop Mobile Apps Using Ionic Framework Series. You can see the first part with the link down below - [Develop Mobile Apps Using Ionic Framework Part-1]( https://utopian.io/utopian-io/@exploringworld/qnj1e-develop-mobile-apps-using-ionic-framework-part-1) <br /><hr/><em>Posted on <a href="https://utopian.io/utopian-io/@exploringworld/develop-mobile-apps-using-ionic-framework-part-2">Utopian.io - Rewarding Open Source Contributors</a></em><hr/>
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":12256376,"name":"ionic","full_name":"ionic-team/ionic","html_url":"https://github.com/ionic-team/ionic","fork":false,"owner":{"login":"ionic-team"}},"pullRequests":[],"platform":"github","type":"video-tutorials","tags":["utopian-io","utopian-io","mobileapps","ionic","tutorial"],"users":["exploringworld"],"links":["https://nodejs.org/en/","https://code.visualstudio.com/","https://git-scm.com/downloads","https://ionicframework.com/docs/v1/guide/preface.html"],"moderator":{"account":"rosatravels","time":"2018-04-28T03:06:00.375Z","pending":true,"reviewed":false,"flagged":false},"questions":null,"score":null,"total_influence":null,"staff_pick":null,"staff_pick_by":null,"config":{"questions":[{"question":"How many substantial concepts does this tutorial address?","question_id":"vtuts-1","answers":[{"answer":"4-5 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-1","value":10},{"answer":"2-3 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-2","value":5},{"answer":"1 substantial concept covered in the tutorial.","answer_id":"vtuts-1-a-3","value":2},{"answer":"More than 5 substantial concepts covered in the tutorial.","answer_id":"vtuts-1-a-4","value":0}]},{"question":"How informative is the content included alongside the video?","question_id":"vtuts-2","answers":[{"answer":"Exceptionally good text and, when applicable, images for concepts covered.","answer_id":"vtuts-2-a-1","value":10},{"answer":"Thorough text and, if applicable, images for concepts covered.","answer_id":"vtuts-2-a-2","value":5},{"answer":"Minimal text and images.","answer_id":"vtuts-2-a-3","value":3},{"answer":"No or very little text and images.","answer_id":"vtuts-2-a-4","value":0}]},{"question":"Is the video clearly prepared and structured?","question_id":"vtuts-3","answers":[{"answer":"Both the presenter and the video are exceptionally organized, structured and presented","answer_id":"vtuts-3-a-1","value":20},{"answer":"Presenter is prepared and video concepts are structured.","answer_id":"vtuts-3-a-2","value":16},{"answer":"Presenter has moments when he/she seems unprepared and/or the content seems to be unstructured.","answer_id":"vtuts-3-a-3","value":8},{"answer":"Presenter seems unprepared and/or video is unstructured.","answer_id":"vtuts-3-a-4","value":0}]},{"question":"Does the contributor provide supplementary resources, such as code and sample files in the contribution post or a GitHub repository?","question_id":"vtuts-4","answers":[{"answer":"Contributor provided exceptional supplementary resources.","answer_id":"vtuts-4-a-1","value":5},{"answer":"Contributor provided good supplementary resources.","answer_id":"vtuts-4-a-2","value":4},{"answer":"Contributor provided minimal supplementary resources.","answer_id":"vtuts-4-a-3","value":1.5},{"answer":"No supplementary resources were provided.","answer_id":"vtuts-4-a-4","value":0}]},{"question":"How would you describe the sound quality of the video?","question_id":"vtuts-5","answers":[{"answer":"Sound quality is excellent and sounds professionally produced.","answer_id":"vtuts-5-a-1","value":10},{"answer":"The sound is clear and understandable with complimenting background music / sounds.","answer_id":"vtuts-5-a-2","value":7},{"answer":"Low quality of sound and/or mildly distracting background noise.","answer_id":"vtuts-5-a-3","value":3},{"answer":"Distracting background noise and/or very low quality recording.","answer_id":"vtuts-5-a-4","value":0}]},{"question":"Does the presenter speak clearly and is easy to understand?","question_id":"vtuts-6","answers":[{"answer":"Yes, presenter’s speech is highly engaging and professional.","answer_id":"vtuts-6-a-1","value":10},{"answer":"Yes, the voice-over is easy to understand.","answer_id":"vtuts-6-a-2","value":7},{"answer":"Only some of the voice-over was comprehensible.","answer_id":"vtuts-6-a-3","value":2},{"answer":"The voice-over was impossible to understand / not included at all.","answer_id":"vtuts-6-a-4","value":0}]},{"question":"Are the title of the tutorial and the concepts being covered present on the video in text overlay form?","question_id":"vtuts-7","answers":[{"answer":"Title and concepts covered are present in the video at all times in a non-disruptive way.","answer_id":"vtuts-7-a-1","value":5},{"answer":"Title and concepts covered appear temporarily when they are addressed.","answer_id":"vtuts-7-a-2","value":4.5},{"answer":"Only the title is presented and the concepts shown are not addressed in overlay text.","answer_id":"vtuts-7-a-3","value":2},{"answer":"Neither title nor concepts covered are presented in the video text overlay.","answer_id":"vtuts-7-a-4","value":0}]},{"question":"How would you describe the formatting, language and overall presentation of the post?","question_id":"c-1","answers":[{"answer":"The post is of very high quality.","answer_id":"c-1-a-1","value":10},{"answer":"The post is of decent quality, but not spectacular in any way.","answer_id":"c-1-a-2","value":7},{"answer":"The post is poorly written and/or formatted, but readable.","answer_id":"c-1-a-3","value":3},{"answer":"The post is really hard to read and the content is barely understandable.","answer_id":"c-1-a-4","value":0}]},{"question":"How would you rate the overall value of this contribution on the open source community and ecosystem?","question_id":"c-2","answers":[{"answer":"This contribution brings great and impactful value, and can be used for applications outside the specific project.","answer_id":"c-2-a-1","value":20},{"answer":"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.","answer_id":"c-2-a-2","value":16},{"answer":"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.","answer_id":"c-2-a-3","value":8},{"answer":"This contribution adds no value to the open source community and ecosystem or the specific project.","answer_id":"c-2-a-4","value":0}]}]}}
Transaction InfoBlock #21950929/Trx 5159358fc5bf71b736e30f8192e8ef1996a4706f
View Raw JSON Data
{
  "trx_id": "5159358fc5bf71b736e30f8192e8ef1996a4706f",
  "block": 21950929,
  "trx_in_block": 20,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-28T03:06:00",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "exploringworld",
      "permlink": "develop-mobile-apps-using-ionic-framework-part-2",
      "title": "Develop Mobile Apps Using Ionic Framework Part-2",
      "body": "#### Welcome to the Second Video Tutorial of Mobile Apps Development using Ionic Framework\n<center> <img src= https://imgur.com/hByL8VX.jpg/> </center>\n\n#### What Will I Learn?\n\n- You will learn how to develop amazing mobile apps using **Ionic Framework** and **Cordova**\n- You will learn the working of **folder and files** of Ionic Framework\n- You will learn about **Ionic header, Ionic content and Ionic footer**\n- Your will learn about **app.js** and **controllers.js** files\n- Your will learn regarding **ionic classes and ion pain** usage\n\n\n\n#### Requirements\n##### System Requirements:\n\n- [Node.js](https://nodejs.org/en/) for building apps\n- [Visual Studio Code](https://code.visualstudio.com/) for code editing \n- [Git](https://git-scm.com/downloads) **(Optional)** or Command Prompt or Terminal\n- An Android or iOS Emulator or mobile device for testing\n##### OS Support:\n\n- Windows 7/8/10\n- macOS \n- Linux \n#### Difficulty\n\n\n\n- Intermediate\n\n#### Required Understanding\n- You just need a little bit of knowledge of HTML,CSS and JS\n- A fair understanding of Programming \n- A thirst for learning and developing something new\n\n\n#### Description\n-\tThis particular video tutorial Series is for everyone who would like to build amazing Android and iOS apps. In this tutorial, you will learn about Ionic Framework with AngularJS from the beginning, that allows you to develop amazing mobile apps with just **HTML, CSS** and **JS**.\n-\tAll you need is a little bit of understanding of web design\t . If you are a web developer and want to build mobile apps, Ionic will probably be your piece of cake. You will be able to create amazing apps that will work on both Android and iOS.\n#### What is Ionic Framework ?\nIonic is an HTML5 mobile app development framework targeted at building hybrid mobile apps. Hybrid apps are essentially small websites running in a browser shell in an app that have access to the native platform layer. Hybrid apps have many benefits over pure native apps, specifically in terms of platform support, speed of development, and access to 3rd party code.\nThink of Ionic as the front-end UI framework that handles all of the look and feel and UI interactions your app needs in order to be compelling. Kind of like **“Bootstrap for Native”** but with support for a broad range of common native mobile components, slick animations, and beautiful design. [Source](https://ionicframework.com/docs/v1/guide/preface.html)\n#### Some of the key steps that are used in this tutorial\n*_Below I discuss important coding steps that are must required in this video tutorial_*\n##### STEP 1:\nNow we have learn about how to develop apps using ionic and also \nhow to deploy them on platform. Now we open the `index.html`file \nIn the visual studio code and then at the bottom there is a **body**\ntag in which there is `<ion-pain>` which contains `<ion-header>` and `<ion-content>` tags, ion-content is basically a container which helps you to organize your content.It allows you to encapsulate your data\n<center> <img src= https://imgur.com/KS8yvPr.jpg/> </center>\n\n##### STEP 2:\nNow inside the `<ion-pain>` tag we are going to change the title of our `header` as well as the `class` of our header. To change the color of our header classes provide different types of color combinations for our **headers**\nSo we change the title to **First App** and change the class to `bar-positive`which turns the color of our header to nice blue color.\n<center> <img src= https://imgur.com/m3jPryB.jpg/> </center>\n\n\n<center> <img src= https://imgur.com/BpkkQrq.jpg/> </center>\n\n##### STEP 3:\nWe can use  `<div>` container here as well in place of `<ion-header-bar>`So it will be easier for us to add more functionality easily\n<center> <img src= https://imgur.com/GgWANt2.jpg/> </center>\n\n\n<center> <img src= https://imgur.com/w8nM9K6.jpg/> </center>\n\n##### STEP 4:\nNow we can also use `<div>`tag to define footer at the end of the code by using `bar bar-footer bar-calm` tag which defines a cool footer with a blue color at the bottom of our app showing in the emulator and named as **This is the footer**\n<center> <img src= https://imgur.com/xHK0rgp.jpg/> </center>\n\n\n<center> <img src=https://imgur.com/4GMVCRE.jpg/> </center>\n\n_*So our changes in the header and footer classes will look like this*_\n<center> <img src= https://imgur.com/x9KEFpY.jpg/> </center>\n\n\n#### Video Tutorial\nhttps://youtu.be/VBRHXQbdjDA\n#### Curriculum\nThis video is second video of the Develop Mobile Apps Using Ionic Framework Series. You can see the first part with the link down below\n- [Develop Mobile Apps Using Ionic Framework Part-1]( https://utopian.io/utopian-io/@exploringworld/qnj1e-develop-mobile-apps-using-ionic-framework-part-1) \n\n\n\n<br /><hr/><em>Posted on <a href=\"https://utopian.io/utopian-io/@exploringworld/develop-mobile-apps-using-ionic-framework-part-2\">Utopian.io -  Rewarding Open Source Contributors</a></em><hr/>",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":12256376,\"name\":\"ionic\",\"full_name\":\"ionic-team/ionic\",\"html_url\":\"https://github.com/ionic-team/ionic\",\"fork\":false,\"owner\":{\"login\":\"ionic-team\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"video-tutorials\",\"tags\":[\"utopian-io\",\"utopian-io\",\"mobileapps\",\"ionic\",\"tutorial\"],\"users\":[\"exploringworld\"],\"links\":[\"https://nodejs.org/en/\",\"https://code.visualstudio.com/\",\"https://git-scm.com/downloads\",\"https://ionicframework.com/docs/v1/guide/preface.html\"],\"moderator\":{\"account\":\"rosatravels\",\"time\":\"2018-04-28T03:06:00.375Z\",\"pending\":true,\"reviewed\":false,\"flagged\":false},\"questions\":null,\"score\":null,\"total_influence\":null,\"staff_pick\":null,\"staff_pick_by\":null,\"config\":{\"questions\":[{\"question\":\"How many substantial concepts does this tutorial address?\",\"question_id\":\"vtuts-1\",\"answers\":[{\"answer\":\"4-5 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-1\",\"value\":10},{\"answer\":\"2-3 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-2\",\"value\":5},{\"answer\":\"1 substantial concept covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-3\",\"value\":2},{\"answer\":\"More than 5 substantial concepts covered in the tutorial.\",\"answer_id\":\"vtuts-1-a-4\",\"value\":0}]},{\"question\":\"How informative is the content included alongside the video?\",\"question_id\":\"vtuts-2\",\"answers\":[{\"answer\":\"Exceptionally good text and, when applicable, images for concepts covered.\",\"answer_id\":\"vtuts-2-a-1\",\"value\":10},{\"answer\":\"Thorough text and, if applicable, images for concepts covered.\",\"answer_id\":\"vtuts-2-a-2\",\"value\":5},{\"answer\":\"Minimal text and images.\",\"answer_id\":\"vtuts-2-a-3\",\"value\":3},{\"answer\":\"No or very little text and images.\",\"answer_id\":\"vtuts-2-a-4\",\"value\":0}]},{\"question\":\"Is the video clearly prepared and structured?\",\"question_id\":\"vtuts-3\",\"answers\":[{\"answer\":\"Both the presenter and the video are exceptionally organized, structured and presented\",\"answer_id\":\"vtuts-3-a-1\",\"value\":20},{\"answer\":\"Presenter is prepared and video concepts are structured.\",\"answer_id\":\"vtuts-3-a-2\",\"value\":16},{\"answer\":\"Presenter has moments when he/she seems unprepared and/or the content seems to be unstructured.\",\"answer_id\":\"vtuts-3-a-3\",\"value\":8},{\"answer\":\"Presenter seems unprepared and/or video is unstructured.\",\"answer_id\":\"vtuts-3-a-4\",\"value\":0}]},{\"question\":\"Does the contributor provide supplementary resources, such as code and sample files in the contribution post or a GitHub repository?\",\"question_id\":\"vtuts-4\",\"answers\":[{\"answer\":\"Contributor provided exceptional supplementary resources.\",\"answer_id\":\"vtuts-4-a-1\",\"value\":5},{\"answer\":\"Contributor provided good supplementary resources.\",\"answer_id\":\"vtuts-4-a-2\",\"value\":4},{\"answer\":\"Contributor provided minimal supplementary resources.\",\"answer_id\":\"vtuts-4-a-3\",\"value\":1.5},{\"answer\":\"No supplementary resources were provided.\",\"answer_id\":\"vtuts-4-a-4\",\"value\":0}]},{\"question\":\"How would you describe the sound quality of the video?\",\"question_id\":\"vtuts-5\",\"answers\":[{\"answer\":\"Sound quality is excellent and sounds professionally produced.\",\"answer_id\":\"vtuts-5-a-1\",\"value\":10},{\"answer\":\"The sound is clear and understandable with complimenting background music / sounds.\",\"answer_id\":\"vtuts-5-a-2\",\"value\":7},{\"answer\":\"Low quality of sound and/or mildly distracting background noise.\",\"answer_id\":\"vtuts-5-a-3\",\"value\":3},{\"answer\":\"Distracting background noise and/or very low quality recording.\",\"answer_id\":\"vtuts-5-a-4\",\"value\":0}]},{\"question\":\"Does the presenter speak clearly and is easy to understand?\",\"question_id\":\"vtuts-6\",\"answers\":[{\"answer\":\"Yes, presenter’s speech is highly engaging and professional.\",\"answer_id\":\"vtuts-6-a-1\",\"value\":10},{\"answer\":\"Yes, the voice-over is easy to understand.\",\"answer_id\":\"vtuts-6-a-2\",\"value\":7},{\"answer\":\"Only some of the voice-over was comprehensible.\",\"answer_id\":\"vtuts-6-a-3\",\"value\":2},{\"answer\":\"The voice-over was impossible to understand / not included at all.\",\"answer_id\":\"vtuts-6-a-4\",\"value\":0}]},{\"question\":\"Are the title of the tutorial and the concepts being covered present on the video in text overlay form?\",\"question_id\":\"vtuts-7\",\"answers\":[{\"answer\":\"Title and concepts covered are present in the video at all times in a non-disruptive way.\",\"answer_id\":\"vtuts-7-a-1\",\"value\":5},{\"answer\":\"Title and concepts covered appear temporarily when they are addressed.\",\"answer_id\":\"vtuts-7-a-2\",\"value\":4.5},{\"answer\":\"Only the title is presented and the concepts shown are not addressed in overlay text.\",\"answer_id\":\"vtuts-7-a-3\",\"value\":2},{\"answer\":\"Neither title nor concepts covered are presented in the video text overlay.\",\"answer_id\":\"vtuts-7-a-4\",\"value\":0}]},{\"question\":\"How would you describe the formatting, language and overall presentation of the post?\",\"question_id\":\"c-1\",\"answers\":[{\"answer\":\"The post is of very high quality.\",\"answer_id\":\"c-1-a-1\",\"value\":10},{\"answer\":\"The post is of decent quality, but not spectacular in any way.\",\"answer_id\":\"c-1-a-2\",\"value\":7},{\"answer\":\"The post is poorly written and/or formatted, but readable.\",\"answer_id\":\"c-1-a-3\",\"value\":3},{\"answer\":\"The post is really hard to read and the content is barely understandable.\",\"answer_id\":\"c-1-a-4\",\"value\":0}]},{\"question\":\"How would you rate the overall value of this contribution on the open source community and ecosystem?\",\"question_id\":\"c-2\",\"answers\":[{\"answer\":\"This contribution brings great and impactful value, and can be used for applications outside the specific project.\",\"answer_id\":\"c-2-a-1\",\"value\":20},{\"answer\":\"This contribution adds significant value to the open source community and ecosystem, or is of critical importance to the specific project.\",\"answer_id\":\"c-2-a-2\",\"value\":16},{\"answer\":\"This contribution adds some value to the open source community and ecosystem or is only valuable to the specific project.\",\"answer_id\":\"c-2-a-3\",\"value\":8},{\"answer\":\"This contribution adds no value to the open source community and ecosystem or the specific project.\",\"answer_id\":\"c-2-a-4\",\"value\":0}]}]}}"
    }
  ]
}
2018/04/28 00:25:15
voteryokunjon
authorexploringworld
permlinkre-yokunjon-re-exploringworld-qnj1e-develop-mobile-apps-using-ionic-framework-part-1-20180427t182329078z
weight10000 (100.00%)
Transaction InfoBlock #21947715/Trx 34d576c7a62c723286e3c6f17e43fee044e19ab6
View Raw JSON Data
{
  "trx_id": "34d576c7a62c723286e3c6f17e43fee044e19ab6",
  "block": 21947715,
  "trx_in_block": 24,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-28T00:25:15",
  "op": [
    "vote",
    {
      "voter": "yokunjon",
      "author": "exploringworld",
      "permlink": "re-yokunjon-re-exploringworld-qnj1e-develop-mobile-apps-using-ionic-framework-part-1-20180427t182329078z",
      "weight": 10000
    }
  ]
}
2018/04/27 22:29:18
voterthetroublenotes
authorexploringworld
permlinkdevelop-mobile-apps-using-ionic-framework-part-2
weight20 (0.20%)
Transaction InfoBlock #21945396/Trx 9cce14856cb1b7f44e97753c4c04d54ab9e4bb11
View Raw JSON Data
{
  "trx_id": "9cce14856cb1b7f44e97753c4c04d54ab9e4bb11",
  "block": 21945396,
  "trx_in_block": 1,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-27T22:29:18",
  "op": [
    "vote",
    {
      "voter": "thetroublenotes",
      "author": "exploringworld",
      "permlink": "develop-mobile-apps-using-ionic-framework-part-2",
      "weight": 20
    }
  ]
}
2018/04/27 22:28:42
votertrendingbot
authorexploringworld
permlinkdevelop-mobile-apps-using-ionic-framework-part-2
weight7000 (70.00%)
Transaction InfoBlock #21945384/Trx 9e25e4f590e72af06ea3e95bee45ae4d9820b9e1
View Raw JSON Data
{
  "trx_id": "9e25e4f590e72af06ea3e95bee45ae4d9820b9e1",
  "block": 21945384,
  "trx_in_block": 14,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-27T22:28:42",
  "op": [
    "vote",
    {
      "voter": "trendingbot",
      "author": "exploringworld",
      "permlink": "develop-mobile-apps-using-ionic-framework-part-2",
      "weight": 7000
    }
  ]
}

Account Metadata

POSTING JSON METADATA
profile{"cover_image":"https://i.imgur.com/dpZ1sar.jpg","profile_image":"https://i.imgur.com/ZGTrViJ.jpg","about":"Love the Nature ★ Enjoy Food ★ Care to Beauty ★ Surf the Tech","name":"Exploring World","location":"Worldwide"}
JSON METADATA
profile{"cover_image":"https://i.imgur.com/dpZ1sar.jpg","profile_image":"https://i.imgur.com/ZGTrViJ.jpg","about":"Love the Nature ★ Enjoy Food ★ Care to Beauty ★ Surf the Tech","name":"Exploring World","location":"Worldwide"}
{
  "posting_json_metadata": {
    "profile": {
      "cover_image": "https://i.imgur.com/dpZ1sar.jpg",
      "profile_image": "https://i.imgur.com/ZGTrViJ.jpg",
      "about": "Love the Nature ★ Enjoy Food ★ Care to Beauty ★ Surf the Tech",
      "name": "Exploring World",
      "location": "Worldwide"
    }
  },
  "json_metadata": {
    "profile": {
      "cover_image": "https://i.imgur.com/dpZ1sar.jpg",
      "profile_image": "https://i.imgur.com/ZGTrViJ.jpg",
      "about": "Love the Nature ★ Enjoy Food ★ Care to Beauty ★ Surf the Tech",
      "name": "Exploring World",
      "location": "Worldwide"
    }
  }
}

Auth Keys

Owner
Single Signature
Public Keys
STM67Mp9MA1ha6UFFW4FaqhDmYhTjKmhx2Tre6183itJhDNMuRh9x1/1
Active
Single Signature
Public Keys
STM5TsBxLQPfwrZeLrA32amGhkxR6tMvAiCo5vpkwCcaZSFJ9jGV71/1
Posting
Single Signature
Public Keys
STM5qtdLHtFCJ5UD78KnGrLsDnX9quESVqx9AP7zo5ySKUgz9GNaH1/1
App Permissions
Memo
STM66yD8tvh73V9fyF4iMv7mmoic3CaXXcstJ667SCNx36j6uKenj
{
  "owner": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM67Mp9MA1ha6UFFW4FaqhDmYhTjKmhx2Tre6183itJhDNMuRh9x",
        1
      ]
    ]
  },
  "active": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM5TsBxLQPfwrZeLrA32amGhkxR6tMvAiCo5vpkwCcaZSFJ9jGV7",
        1
      ]
    ]
  },
  "posting": {
    "weight_threshold": 1,
    "account_auths": [
      [
        "esteemapp",
        1
      ],
      [
        "utopian.app",
        1
      ]
    ],
    "key_auths": [
      [
        "STM5qtdLHtFCJ5UD78KnGrLsDnX9quESVqx9AP7zo5ySKUgz9GNaH",
        1
      ]
    ]
  },
  "memo": "STM66yD8tvh73V9fyF4iMv7mmoic3CaXXcstJ667SCNx36j6uKenj"
}

Witness Votes

0 / 30
No active witness votes.
[]