How to use raw js to get the exact params and use them or pass them along. it turns out we can simplify all this example below and use window.search.location and pass that entire string along. much more dynamic
Example from webflow setup
window.addEventListener('DOMContentLoaded', function () {
// get param values from url
var voucherCode = getParam('voucher');
// var psUser = getParam('psuser');
// var ttclid = getParam('ttclid');
// var utmSource = getParam('utm_source');
// var utmMedium = getParam('utm_medium');
// var utmCampaign = getParam('utm_campaign');
var allParams = window.location.search
// build params -- array of params we want to listen for and append to ctas
// var paramArray = [['voucher', voucherCode], ['psuser', psUser], ['ttclid', ttclid], ['utm_source', utmSource], ['utm_medium', utmMedium], ['utm_campaign', utmCampaign]];
// var voucherParams = buildParams(paramArray);
// var addVoucherParams = addParams(paramArray);
var ctas = document.querySelectorAll('a[href*="homechef"]');
var bannerCopy;
var voucherApi = "https://www.homechef.com/api/landers/vouchers/" + voucherCode;
// code validation -- every param checks always necessitates a voucher code
if (validCode(voucherCode)) {
$.ajax({
url: voucherApi,
headers: {
'Authorization': "Basic " + btoa("landers" + ":" + "bRr5d3huEaOsNHAWLGI3"),
'Content-Type': 'text/plain'
},
method: 'GET',
crossDomain: true,
success: function (response) {
if (response.voucher) {
bannerCopy = response.voucher.message;
if (response.voucher.disclaimer) {
if (!$('.disclaimer').length) $('.footer').append("<div class='disclaimer'></div>");
$('.disclaimer').html(response.voucher.disclaimer);
$('.disclaimer').find('a').css( {"color":"red", "text-decoration": "none"});
}
} else if (response.error) {
bannerCopy = response.error.message;
}
if (bannerCopy !== "") {
var mobileBannerMargin = $('.voucher-bar-2-2').css('height');
$('.voucher-text').text(bannerCopy);
$('.voucher-div').parent('div').show();
$('.body').css('margin-bottom', mobileBannerMargin);
}
}
});
for (var i = 0; i < ctas.length; i++) {
// CTAs have param already
if (ctas[i].href.indexOf("?") != -1) { // has params already
var allParamsMinusQuestionMark = allParams.substring(1)
ctas[i].href += allParamsMinusQuestionMark;
} else {
// Add Brand New param string
ctas[i].href += allParams;
}
}
}
// Add padding for cta on bottom of page
var pageBottomPadding = $('#mobile-cta').outerHeight(true);
$('body').css('padding-bottom', (pageBottomPadding + 'px'));
});
// New Param String
// function buildParams(paramArray) {
// var paramString = '';
// if (paramArray.length < 1) return null;
// for(var i = 0; i < paramArray.length; i++) {
// if (paramArray[i][1] != null) {
// if (i === 0) {
// paramString += '?';
// } else {
// paramString += '&';
// }
// paramString += paramArray[i][0] + '=' + paramArray[i][1];
// }
// }
// return paramString;
//}
// Append to existing param string
function addParams(paramArray) {
var paramString = '';
if (paramArray.length < 1) return null;
for(var i = 0; i < paramArray.length; i++) {
if (paramArray[i][1] != null) {
paramString += '&';
paramString += paramArray[i][0] + '=' + paramArray[i][1];
}
}
return paramString;
}
// will filter out empty or null params
function getParam(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
if(results === null) return null;
// the param value is empty or null
return (results[1] === '' || results[1] === null) ? null : decodeURIComponent(results[1].replace(/\+/g, " "));
}
function validCode(code) {
if (!code || code == '') {
return false;
}
var regex = /^[a-zA-Z0-9]{2,20}$/;
var found = code.match(regex);
return (found ? true: false);
}
useMemo react hook
In the example below, only run the if statement if [meals, meal, reviews]
has changed. It's expensive and more performant to only run if something has updated or changed.
const review = useMemo(() => {
if (meal) {
const selectedMeal = Object.values(meals).find(m => meal.id === m.mealId);
return selectedMeal ? reviews[selectedMeal.id] : null;
}
}, [meals, meal, reviews]);
a little more info about the useMemo
hook https://www.digitalocean.com/community/tutorials/react-usememo
Understanding an index and when to use it
An index helps with performance when doing a query on a column. If a column will be directly queried it's a good idea/practice to do an add_index
migration.
Working from home due to coronavirus has taught me a lot more about working indenpently and how to better frame and ask my questions through chat. I ask questions once I'm really stuck since I can't just go up to someone and have them look at my laptop. This slows down the process but it also has given more confidence to ask question in slask channels and in chats. Also more confidence to reach out to new people.
sql refresher - Order is, first you get your things, then you narrow it down, then it order it and then you limit it. Database is going to be way faster than having ruby do it. Database was designed to be fast for these operations.
SELECT * FROM recipes WHERE prep_time > 100 OR chef = 'person' LIMIT 1.
ORDER BY prep_time DESC;
WHERE ingredients LIKE '%bread%';
Functions that give you some extra power
SELECT COUNT(*) FROM recipe;
SELECT SUM(prep_time) FROM recipes;
SELECT AVG(prep_time) FROM recipes WHERE chef = 'Ashley;
Conditional onClick
method with multiple mehtods in react.
onClick={() => {
if (rating === 5) this.props.onSetShowFeedback(true);
this.updateComment();
}}
or another way to write this could be
onClick={() => {
rating === 5
? [this.updateComment(), this.props.onSetShowFeedback(true)]
: this.updateComment();
}}
Also, as a note it's better to pass in display-oriented prop name? Instead of rating === 5
it would be better to use what's happening, like showInvitationForm
Realized something fundamental about react syntax. The component section, everything after the && is just a truthy statement. This below is like saying if basket.future
is truthy (which it is), then move on render the next thing.
{basket.futureBasket && (
<FutureBasketButtons basket={basket} onUnskip={onUnskip} onSkip={onSkip} />
)}
includes
keywords means you are using a module.
Inheritance works well in certain situations and modules work well in other situations.
move chunks of code in sublime: highlight code and click option and move the arrows up and down to move chunks of code.
command d - highlight the word and command d finds all of the word in the same file
Look into spree getting started tutorial for open source rails ecommerce applications: https://guides.spreecommerce.org/developer/tutorials/getting_started_tutorial.html
First day as a TA!!
some lecture take aways: github - why is it benefitial to put your code online in open source so anyone can look at it?
- programmings can fix bugs or make code better for companies that are interesting to you and you can prove your value
- microsoft used to be completly closed and private. In 2017 they opened up. We live in a pendulum. In the future could be different. In different industries things are very closed and keep their secrets but in the software world this is the opposite.
solving problems: break the problem down to the simplest thing you can solve and then move forward. It a lot more fun than getting stuck.
For example:
class Employee
attr_reader :first_name, :last_name, :active
attr_writer :active
def initialize(input_options)
@first_name = input_options[:first_name]
@last_name = input_options[:last_name]
@salary = input_options[:salary]
@active = input_options[:active]
end
def print_info
puts "#{@first_name} #{@last_name} makes #{@salary} a year."
end
def give_annual_raise
@salary = 1.05 * @salary
end
end
employee1 = Employee.new({ first_name: "Majora", last_name: "Carter", salary: 80000, active: true })
employee2 = Employee.new(first_name: "Danilo", last_name: "Campos", salary: 70000, active: true)
employee1.print_info
employee2.print_info
class Manager < Employee
def initialize(input_options)
super(input_options)
@employees = input_options[:employees]
end
def send_report
puts "Sending email..."
# use email sending library
puts "Email sent!"
end
end
manager = Manager.new(first_name: "Saron", last_name: "Yitbarek", salary: 100000, active: true, employees: [employee1, employee2])
manager.print_info
manager.send_report
p manager
Create a method in the Manager class called give_all_raises
that loops through each of the manager’s employees and gives them a raise (using the give_annual_raise
method). Demonstrate how it works.
Don't just start writing a loop. 1. Write a method called give_all_raises
that just puts "something" and make sure that works, then try to just return an employee. Then return each employee and then write the loop via the long way and then use the .each shortcut.
find_by vs find_by!
.find_by
will return a nil when record isn’t found. .find_by!
will return ActiveRecord::RecordNotFound
.
React: How to set a modal to only show one time by storing this in local storage
- Setup local storage helpers
import once from 'lodash/once';
const PREFIX = 'HomeChefSession';
export const markSeen = (type, name) => set(`${PREFIX}_${type}_${name}`, 1);
export const wasSeen = (type, name) => get(`${PREFIX}_${type}_${name}`) == 1;
const isAvailable = once(() => {
try {
const key = '__TEST__';
localStorage.setItem(key, key);
localStorage.getItem(key);
localStorage.removeItem(key);
return true;
} catch (e) {
return false;
}
});
const get = key => {
if (!isAvailable()) {
console.warn('localStorage is unavailable');
return;
}
return localStorage.getItem(key);
};
const set = (key, val) => {
if (!isAvailable()) {
console.warn('localStorage is unavailable');
return;
}
localStorage.setItem(key, val);
};
- Create logic for when the modal should be shown
onAddMeal = ({ mealId }) => {
if (mealId === SUPER_BOWL_MEAL_ID) this.handleSuperBowlModal();
};
- Set the state of of the modal to false. Create logic to set the modal to
wasSeen
and set the state of the modal to true.
handleSuperBowlModal() {
const takeoverKey = `modal_${SUPER_BOWL_MEAL_ID}`;
const takeoverSeen = wasSeen('takeover', takeoverKey);
if (takeoverSeen) return;
this.setState({ showSuperBowlModal: true }, () => markSeen('takeover', takeoverKey));
}
messageStyle={
globalMessage.action === Types.SHOW_MODAL_ACTION ||
Types.SHOW_JANUARY_RESTART_MODAL_ACTION
? 'success'
: 'error'
}
I think this may not be evaluating in the way you think -- globalMessage.action === Types.SHOW_MODAL_ACTION
will always evaluate first, and if that's false, this will return Types.SHOW_JANUARY_RESTART_MODAL_ACTION, which is a truthy value. So I think we'll always be setting returning success here.
We could fix this by comparing globalMessage.action to both values like this:
globalMessage.action === Types.SHOW_MODAL_ACTION || globalMessage.action === Types.SHOW_JANUARY_RESTART_MODAL_ACTION or using includes:
[Types.SHOW_MODAL_ACTION, Types.SHOW_JANUARY_RESTART_MODAL_ACTION].includes(globalMessage.action)
Today I learned about time travelling for tests. I needed ot test that a job would run one week after a delivery_date
. I can't update the date because it's not an attribute. It's created from a series of methods. I thought I solved the problem by testing after travel_to first_basket.delivery_date + 1.week
and was so proud of myself for figuring this out!!
Everything passed locally when I ran it. But then on codeship certain tests were failing. I couldn't figure it out. After travelling in time you have to travel_back
or the test suite will be left in the wrong time and any time related tests will fail https://api.rubyonrails.org/v5.2.3/classes/ActiveSupport/Testing/TimeHelpers.html#method-i-travel_back
Active Record queries and scope refreshers. Scope is like a usuallable query that is set on the model. This allows you to narrow down the search.
Example below - we want to find each basket that is for a specific menu (scope
is for_menu(menu)
defined on the weekly_basket.rb model. scope :for_menu, -> (menu) { where(menu: menu) }
. delivered and first_order are also scope. This allows us to drill down in a reusable way.
WeeklyBasket.for_menu(Menu.previous).delivered.first_order.find_each do |wb|
user = wb.user
MessageCenter::ReferralCredit.create!(user: user)
A note about return arrays in active record. If something like #<WeeklyBasket::ActiveRecord_Relation:0x3fd3eb2342a0>
is returned run the same query with .first at the end to see what the query is actually returning.
Problem: Today I came across a task where I needed to make an update in a rails controller and route to a path that takes the user to a the dashboard (a react page).
def create
if current_user.meal_plan == MealPlan.fresh_and_easy
current_user.update(meal_plan: MealPlan.standard)
end
redirect_to root_path
end
Upon landing on the react page a toast message (which is a javascript component) would then load letting the user know that their meal plan has changed. I could see in the Redux store that I could access the current meal plan and my challenge was to determine how to get this information from rails to react.
We decided to set the session data to a variable called meal_plan_changed
def create
if current_user.meal_plan == MealPlan.fresh_and_easy
current_user.update(meal_plan: MealPlan.standard)
elsif current_user.meal_plan == MealPlan.standard
current_user.update(meal_plan: MealPlan.fresh_and_easy)
end
session[:meal_plan_changed] = { value: "true", expires: 50.seconds.from_now }
redirect_to root_path
end
The problem here is that the session data will only ever be available server side (controllers and rails view templates, but not react directly). In order to get this to js I could add a little bit of JavaScript in a rails template which sets some carefully named global variable. Then when the dashboard mounts, check if that’s set and do a toasr. Or I could stash it in a hidden div with a unique id and pull it out of the DOM.
In app/views/shared
I found a erb file that this variable could live in.
<script type="text/javascript" charset="utf-8">
window.HomeChef = HomeChef || {};
<% if user_signed_in? %>
HomeChef.currentUser = {
isCustomer: <%= current_user %>,
meal_plan_changed: "<%= session[:meal_plan_changed][:value] || false %>",
};
<% end %>
</script>
I inspected the elements in the dashboard and in the browser to see that I had access to this global variable.
var HomeChef = HomeChef || {};
HomeChef.currentUser = {
isLoggedIn: true,
meal_plan_changed: "TRUE"
};
Some next steps could be to update the Redux store. In the dashboard initial status app/javascript/reducers/dashboard/status.js
I could add
const initialState = {
hasMealPlanChanged: window.HomeChef.currentUser.meal_plan_changed,
};
In the end we decided not to go with route and decided to create flash alerts in rails to avoid this but overall good learning experience. Here's stackoverflow article explaining why this isn't the best approach: https://stackoverflow.com/questions/29101320/how-to-access-session-information-from-within-model
Sidenote: good resource for suggested apps to use: https://wesbos.com/uses/
Here are some examples of what to look for when testing a backfill from csv file. What do we want to happen? We want to add a method that will grab all the ids and batch them. Once we have these batches, we will create method that creates the csv file. Each colunn will have a different applicable attribute. We can test this by running these methods in the rails console.
If sideqik isn't set up locally, you will have to run .new.perform
vs .perform_async
. To test with sideqik push to a demo environment and confirm all the env variables are set up correctly.
Test with 1 or 2 specific users in the console
User.where(id: [6512273, 2923692]).select(:id).find_in_batches(batch_size: 100_000) do |user_batch|
HandleBatch.perform_async(user_batch.map(&:id))
end
end
end
Take a look at all the include files and see if any environment variables are missing
class HandleBatch
include Sidekiq::Worker
include S3UploadAndNotify
sidekiq_options queue: :non_scaled_high_volume
Confirm the path in S3 browser. Add any missing folders
CSV_PATH = 'salesforce_marketing_cloud/triggered_automations/user_uuid'
def perform(user_ids)
CSV.open(tmp_file_name, "w") do |row|
row << %w(id uuid)
user_ids.each do |user_id|
uuid = User.find(user_id).uuid
row << [user_id, uuid]
end
end
Look through the other classes (for example, FtpUploadWorker
to see what is actually happening
file = upload_to_s3(CSV_PATH).internal_url
SalesforceMarketingCloud::FtpUploadWorker.perform_async(file)
end
Check the /tmp
file to see if the files are actually being created.
def tmp_file_name
@tmp_file_name ||= Rails.root.join("tmp","user_uuid_#{Time.current.strftime("%Y%m%d%H%M%S%L")}.csv").to_s
end
end
end
- JS tests can
findByText
but what do you do in a situation when the text changes at a smaller breakpoint? You can usefindByTestId
. For example -<div data-testid="edit-meals">Edit Meals</div>
it('renders only Edit Meals and Settings buttons', async () => {
const { findByTestId } = finders;
expect(findByTestId('edit-meals')).toBeTruthy();
});
Fixed a bug that occured when payment was being taken after a gift card was created so a user would recieve a gift card if the payment failed. I learned how to trigger a salesforce job and check for errors to resolve. We reordered the jobs so that a new gift wouldn't be created if the payment failed. Updated our tests to fix what we broke in this process.
rescue
keyword: use this to redirect or render something if something failed or errored when it was runningraise
is used to start the issue if there is a problemrollbar
is a program that alerts our team to know that there was an error. We can use this to alert us that somethign went wrong. For example,Rollbar.critical(e, "Card was charged but not gift card was sent!", @cart)
https://www.honeybadger.io/blog/a-beginner-s-guide-to-exceptions-in-ruby/
Helped a colleague with flex-box today. He had several cards on a page and wanted them to be evenly spaced and with a margin. The last row was unevenly spaced because all the rows had 4 cards and the last one had 3 cards.
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
&:after {
content: "";
flex: 1 1 24%;
}
Use lodash
a library to iterate over objects with redux. You can also use this for iterating with arrays because it deals with falsy values.
//import the library
import _ from "lodash"
//use it
_.map(users, (user) => {
return <User />
})
libraries for fake data - yarn add shortid txtgen faker
const shortid = require("shortid"); // shortid.generate() returns a unique "short" id
const txtgen = require("txtgen"); // txtgen.sentence() returns random "readable" sentences
const faker = require("faker"); // faker is used for generating random fake data.
Steps for creating a payment form and storing credit card information using stripe: https://stripe.com/docs/recipes/elements-react#setup
- Install dependencies and set up the project
- Create the payment form component
- Create a token to securely transmit card information
- use an env var for the token
- Changing the font style on the stripe input
<CardElement style={{ base: { fontFamily: 'Muli, Helvetica Neue', fontWeight: 300 } }} />
Save for later: https://hibbard.eu/rails-react-crud-app/
Trying to get a greater understanding for what is happening in git. I don't want to just blindly type commands but actually understand what I'm doing: https://dev.to/unseenwizzard/learn-git-concepts-not-commands-4gjc
Used selectors to work with styling to have styles happen at different clicks and focuses for the navbar. Used this to fix a bug when two navlinks were staying styled upon opening in a new tab.
&:visited
&:focus
&:active
&:hover
&::after
“With React 16
, you don’t have to wrap adjacent JSX
elements in a div
. You can use an array if you want - but pass in a key prop to each element in the array.”
render() {
return [
<HelloWorld key={1} tech={store.getState().tech} />,
<ButtonGroup key={2} technologies={["React", "Elm", "React-redux"]} />
];
}
Excerpt From: Ohans Emmanuel. “Understanding Redux - 1.”
- Emojis to use in markdown: https://gist.github.com/rxaviers/7360908
- Use contants vs hardcoding.
const ALL_CAPS_NAME = 2;
- Git Lens allows you to see who made changes in the code base and what ticket it's from. You can look it up in github to get more context.
- helpful rails console search:
Meals.find_by_hash_id("2132132")
- managing environment variables in postman
- For usernames, setting the response code to
head :ok
(or any code) regardless of whether it's a real username or not, this way the usernames are not vulnerable if there's a different response 200 vs 404 if the username does or doesn't exist.
git fetch origin
git checkout 11238-the-branch-name
- pull down branch, check what everything looks like in various screen size, zoom in and out, switch to mobile view, go line by line and look up syntax that is new or unfamiliar. Open the local branch and click around. Check if there is something that could make something clearer. Read other people's comments. Ask questions either on the ticket or slack the person. Run the rspec tests if applicable.
-
Styling a tooltip trigger and hoover feature: https://github.com/homechef/mealhand/blob/9555abdd9f6b96646cc3357377fa2f5ef495370e/app/javascript/styles/shared/tooltip.module.scss
-
syntax for testing that a an array if empty
expect(json['ingredients']).to be_empty
if the value isn't present and if the value is present testing that the array matchesexpect(json['ingredients']).to match_array([ { "name" => ingredient_assignment.name, "amount" => ingredient_assignment.formatted_measurement, "allergens" => ingredient_assignment.public_allergen_tags, } ])
-
Started Reading Understanding Redux - https://medium.freecodecamp.org/understanding-redux-the-worlds-easiest-guide-to-beginning-redux-c695f45546f6 (promo code FREECODECAMP)
position: static;
position: absolute;
- give it top bottom left right
- takes it out of the flow and moves
position: relative;
- position it relative to the place that you are laying it
position: fixed;
- takes it out of the flow and puts it in a particular spot
position: sticky
- when fixed won't work for you because you need the div to be fixed at a certain point
practiced using https://flexboxfroggy.com/
Use when you know there is going to be an even amount of space but you don't know the number of divs and it can change. This allows us to avoid the math and margins, etc.
The parent div needs display: flex;
in order for the children to know to flex
justify-content
accepts the following values
flex-start
: alligns items at the right side of the containerflex-end
: alligns items at the left of the containercenter
: center of the containerspace-between
: equal spacing between items within the containerspace-around
: items have equal spacing around them
align-items
or align-self
accept the following values
flex-start
: Items align to the top of the containerflex-end
: Items align to the bottom of the containercenter
: Items align at the vertical center of the containerbaseline
: Items display at the baseline of the containerstretch
: Items are stretched to fit the container
flex-direction
accepts the following values
row
: items are the same as the text directionrow-reverse
: items are placed opposite to the text directioncolumn
: items are in a column top to bottom (this changesalign-items
to be horizontal)column-reverse
: item are in a column bottom to top
example: put the items in the container at the bottom in the middle
#pond { display: flex; flex-direction: row-reverse; justify-content: center; align-items: flex-end; }
order
property - default to 0 but you can set it to the order it should appear in the row/column (-1, 0, 1,)
flex-wrap
accepts the following property
nowrap
: every item fits in a single linewrap
: items wrap around and fit to the next linewrap-reverse
:items wrap around in the reserve order
flex-flow
shorthand to combine flex-direction
and flex-wrap
flex-flow: column wrap
= flex-direction: column; flex-wrap: wrap
align-content
takes the following properties. Determines the spacing between lines. When there is one line, this has no effect
flex-start
: lines start at the top of the containerflex-end
: lines start at the end of the containercenter
: lines are in the center of containerspace-between
: lines have equal spacing between themspace-around
: lines have equal spacing around themstetch
: lines are stretched to fit the container
flex-basis
is kind of like width (can you use px, %, etc.) it will be used to disubute extra space
flex-grow:
give one of the children divs more space than the others (flex-shrink
is the reverse). You have to have at least 2 children divs to use this
rspec notes
- when reusing a very similar
describe
black for the index and show responses it could be worth creating ashared_example
to avoid repeating the code:https://relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples - variables are great tools in tests to help make everything more readable
bundle exec rspec file/path/to/code:line number
Within the config/experiments.ym
experiment_name:
variants: 3 //required
ga_id: "OPTIONAL-GOOGLE-ANALYTICS-ID" //optional
guard_env: OPTIONAL_ENVIRONMENT_VARIABLE_NAME //optional - this is if you want an env in from heroku and you want to turn on or off the experiment
selection_strategy: Experiment::Strategies::OddEvenUserId // how you are determining the strategy
Experiment is added to the controllers. This is if you want to use a cookie or track the experiment in ahoy or google analytics.
If there are 2 variants than 50% of the users have the control and 50% have the experiment. This is randomly assigned based on v = 1 ? 1 : 0
ENV syntax in controller is tricky - ENV.fetch("NAME_OF_ENV", false)
You can write tests for the experiments in the spec/model/{model}.rb. There is particular syntax for the ENV variable in the tests as well.
// Plain function:
function Hi({ name }) {
return <div>Hello {name}!</div>;
}
// A constant holding an anonymous function:
const Hi = function({ name }) {
return <div>Hello {name}!</div>;
}
// Removing the "function" keyword and adding the
// arrow after the parameter list:
const Hi = ({ name }) => {
return <div>Hello {name}!</div>;
}
// Optional step 3: Removing the braces, which makes the
// "return" implicit so we can remove that too. Leaving the parens
// in for readability:
const Hi = ({ name }) => (
<div>Hello {name}!</div>
)
// Optional step 4: If the component is really short, you can put
// it all on one line:
const Hi = ({ name }) => <div>Hello {name}!</div>;
Understanding Redux, Although common to use with React, Redux has no relation to React. Can use with React, Angular, Ember, jQuary or vanilla js. To use with React install npm install --save react-redux
Actions (javascript objects)- describe what happened, now how the state has changed Action Creators (functions that create the actions) Reducers - specifiy how the application's state changes in response to actions. This is a pure function that takes the previous state and an action and returns the next state
(previousState, action) => newState
Store (object that brings together teh actions and reducers)
import todoApp from '/reducers'
const store = createStore(todoApp)
Importance of testing different mobile devices. Set up the Android Studio Emulator - https://docs.expo.io/versions/latest/workflow/android-studio-emulator/ to test the display.
Expo provides styles that make it easier to display on different screens.
container: {
paddingTop: Constants.statusBarHeight,
},
Working on the react native mobile app to include a search feature in the cookbook history. First pull request opened for the mobile app repo.
- Started using Visual Studio Code as opposed to Sublime
- Working with
flex-direction: "row"
justifyContent: "space-between"
flex: 2
also learning about style consistencies to work with styles saved in different file and importing these stylesheets into the component I'm working with - Testing the app simulator on different devices. Just because it works on one iphone doesn't mean it will render properly on others.
Hardware > Device . IOS...
Also worked on a ticket for a header. Worked on some styling and familiarized myself with breakpoints and default spacing and styling for the web application.
LifeCycle of the components in reactjs. Fetching data before rending data to the UI. You don't need to bind lifecycle methods because react will do this for you.
constructor()
- establish initial state of the componentrender()
describes the UI for the particular component render with the intial state and thencomponentDidMount()
Component needs data to render properly. Fetching data would happen here. First time the component is mounted.componentDidUpdate()
After you already of have the component and just need to swap something it will not remount. If the new id is different from the loaded id than run this component update. The component isn't going to remount but a new request based based on the props being passed in renders again and then the component updates again. each time.componentWillUnmount()
component will be removed from the DOM
Loading while fetching data from API
- add to constructor state
loading: true
- add to componentDidMount() state
loading: false
- render something to show this for example
render() { if(this.state.loading === true) { return <h1>LOADING</h1> }
To stop a component from continueing to run use componentWillUnmount
For example:
componentDidMount() { this.interval = window.setInterval(() => { this.setState((currentState) => { return { text: currentState.text + "." } }) }, 300) } //will need to clear the interval so the function doesn't keep running every 300 miliseconds componentWillUnmount() { window.clearInterval(this.interval) }
https://tylermcginnis.com/free-react-bootcamp/
State vs props - props gets passed to the component (similar to function parameters) whereas state is managed within the compenent (similar to variables declared within a function). State is just data in your app.
this.setState - here's the new state of this compenent. React determines how the UI will change based on the new state.
What state does this need? what is the ui going to look like? State = what information is needed in the component
Props short for property. Components take in parameters called props. Disply via the render method.
super is used when defining the constructor. super(props)
constructor(props) { super(props); }
this.state is used so that the component can remember/know/identify that it has been clicked/selected for the next action
shared mutatble state different views are depending on the same state.
react element vs react component component is a function or class which optionally accepts input and returns a react element
We can convert our elements into components by wrapping them in functions
- Merged and Deployed first ticket
- CUstomized terminal using https://iterm2colorschemes.com/
- Install React Dashboard
First IPM (iterative planning meeting)/plan sprint for the week. We talked through Zenhub tasks and tickets and learned about the needs from the product managers and discussed how to move forward. Saw how to PM splits the ticket into multiple projects.
- team member mentioned React big calendar library - interface, day calculation
- Fibanatici number is a number assigned to the ticket to define how complex it is. Also there's fast laner tickets
Rake command function for manipulting the informaiton within the file. Similar to the rails command. Pollyfill.io ability to use new features of javascript in an older browser
Looking for calendar options https://github.com/clauderic/react-infinite-calendar
Worked on my first ticket in Zenhub and created a pull request I updated the maxlength from 400 to 350 and the corresponding yaml file from 400 to 350.
Process for Pull Request
git status
git checkout [file name] - do this for each modified file that you didn't work on
git status - to make sure nothing else changed
git diff - to see our changes
git add .
git commit -m "comment here"
git push origin head
Fist day as a software engineer!
- Learned about New Relic, Rollbar
- Set up Heroku, Slack, Terminal and Homebrew, Bash Profile, Install git, IDE, Postgres, Redis, RBenv, Ruby version 2.3.2, Install yarn, AWS, Zenhub, github
Note: Make sure to use NPM (not Homebrew!) to install. WHY? Homebrew deprecated installing specific versions of packages (like yarn) a while back, and yet Homebrew is still the only secure, “recommended” install method from the Yarn docs.
Spent the day at Google for Women's Techmakers for international women's day. Actions on google (developer platform to make an app that works on google assistant). User invokes the action by saying something. The assistant parses that texts and runs natural language process, converts to speech and offers options.
Dialogflow matches and categorizes user utterances. Itentify key words and phrases spken by the user. Using machine learning to get to the conversation going
SSML - speech sythesis mark up language can help make language sound more natural. Customize assitant to read things in the local dialech
for fun Geekgirl rising trivia game (Say Hey google!)
Make an app and deploy it to be part of the community.
Familiarizing myself with phython syntax, creating a simple dictionary in python.
# Value: Capital
# create an empty dictionary
statesToCapitals = {}
statesToCapitals["Texas"] = "Austin"
statesToCapitals["New York"] = "Albany"
print(statesToCapitals)
Pros/Cons of hash based data structures:
- searching is much faster than array structures but hash maps do take up more space.
- insertion and deletion is also quick regardless of size of hash (o(1) or contanst time)
- Collisions could increase the time and take o(n)
- no sorting with hash based data structions
A collection of unique items, order doesn't matter but nothing is duplicated.It's used to test "membership" of the set
primaryColors = set(["red", "blue", "yellow"])
## is green a primary color?
color = "green"
## if the color exactly matches in lower case the an item in the set
if color.lower() in primaryColors:
#it is a primary color
print(color + " is a primary color")
else:
#it's not a primary color
print(color + " is not a primary color")
primaryColors.add("red")
## nothing changes because red is already there
print(primaryColors)
Java terms - JVM, JDK, JRE? Java virtual machine Jave Development kit (contains the JRE)- what you need to develop java programs Jave Runtime Environment (contains JVM)- what you need to run java programs
Practiced making linked lists in Java.
public class LinkedListFromScratch {
Node head;
//create add method/functionality. this adds it the front of list
public void add (int data) {
//implement the method
//ll is empty
if (this.head == null) {
this.head = new Node(data);
} else {
//ll is not empty
Node nodeToAdd = new Node(data);
nodeToAdd.next = this.head;
this.head = nodeToAdd;
}
}
public static void main (String[] args) {
LinkedListFromScratch myList = new LinkedListFromScratch();
myList.add(10);
myList.add(18);
System.out.println(myList.head.data);
System.out.println(myList.head.next.data);
}
}
//Linked list has a bunch of nodes
//Node
class Node {
int data;
Node next;
Node(int d) { this.data = d;}
}
Today I worked on creating a simple CRM with people, organizations and addresses as their own models (https://github.com/AshleyAbramowiczGibbs/synap-ruby-exercise)
There was a massive CSV file that seeded and explored the CSV library. I used some notes and videos I found online to figure out ho to seed an app with a CSV - https://gist.github.com/arjunvenkat/1115bc41bf395a162084
I deployed it to heroko and learned that heroku does not support sqlite3 , so I used Postgresql instead.
gem 'sqlite3'
end
group :test, :production do
gem 'pg'
end
For the transit app we determined that we can easily grab the location data from the phone by using expo built in features. expo-location module allows reading geolocation information from the device. Your app can poll for the current location or subscribe to location update events.
https://www.npmjs.com/package/expo-location
Used this tutorial to make requests to a sample API to display in React-Native app. https://medium.com/@ahmed.ter001/react-native-simple-card-view-tutorial-b36a1bf8afeb
Trying Axios with react native to make web requests to backend - https://www.npmjs.com/package/react-native-axios
- Database practice: Took a sample architecture problem and created a schema. Defined the tables, attributes and associations (has_many, belongs_to) and the join tables - many to many relationship (table in between to make these happen)
- Refresher on ORM (object relational mapping) - software that allows codebase to communicate with a database (the synatax in your code translates ORM in SQL to communicate with the database)
- Native.Base (the bootstrap for react native apps). Added some components to the transit app after looking at the wireframes to make it look more professional. - https://nativebase.io/ Updated the navbar and played around to see how the different react native components interact with each other.
Flexbox froggy to learn flexbox - new cool CSS to use - https://flexboxfroggy.com/ Grid layout to learn this - https://cssgridgarden.com/ Worked with Sam to get the Dynamic Jewish Guide page in JSON - https://s3.amazonaws.com/sngstemp1/jchicago-guide.json to make web requests to page.
Referencing this github for ideas for Dynamic Vue.js guide - https://github.com/johnayeni/filter-app-vue-js/blob/master/src/data/data.js. Tried using vue.js with components to keep everything organized. Experimented with a couple of different filtering approaches.
Looking into building robots/machines and trying to get a tiny taste of it with NodeBots http://nodebots.io/, more to come (https://www.youtube.com/watch?v=D-HEaGI71eU) Interesting trainings I came across today, going to explore - https://www.girldevelopit.com/materials
- Install Expo https://expo.io/learn expo init my-new-project cd my-new-project expo start
- watched react native tutorial to get started
-
Started learning some regex - https://regexone.com/
- remove all non alpha numeric characters and make the string lower case
``let reg = /[\W_]/g;
let newWord = originalWord.toLowerCase().replace(reg,"");``
-
practiced algorithims on freecodecamp.com https://repl.it/@ashleyabramo2/Practice-Javascript-Problems?language=javascript&folderId=
- Added search filter to Chicago Guide used this template as a reference - https://codepen.io/AndrewThian/pen/QdeOVa
- Discussed plan and features with marketing team
- looked at how other organizations use filtering for ideas and suggestions
- Discovered builtwith - https://builtwith.com, a tool that allows me to look up what languages, frameworks, APIs, etc that a particular application is built with
- Working on Lunch and Learn Presentation
Experimenting with hosting with free services - https://pages.github.com/. Initial commit for https://ashleyabramowiczgibbs.github.io/
set up Heroku https://devcenter.heroku.com/articles/getting-started-with-ruby#set-up
Downloaded Exercism to practice algorithim - https://exercism.io/my/solutions/a7d83e3a123f45339436d90bf9645af3 Continuing to study ruby and javascript algorithims - https://actualize-tech-interviews.herokuapp.com/exercism
Starting 2019 off right - created a new Vue.js project for the Dynamic Guide to Jewish Chicago https://github.com/AshleyAbramowiczGibbs/dynamic-guide-to-jewish-chicago and added Sam as a contributor. Setting up the project by adding a v-for loop to loop through the dummy data and importing vue2filters. Researching other resources.
- Met with Sam to learn about projects to work on for Chitribe
- Puppeteer - allows you to inject code into a page
- starting Vuejs project for Guide to Jewish Chicago - https://chitribe.org/jewishchicagoguide/ (filtering, tagging, sorting, etc.)
- Create Dummy data - how to represent the data as JSON
- google "awesome" + technology to get ideas and resources for project (example)- https://github.com/vuejs/awesome-vue
Jason showed me the project he is working on in R. He showed me some charts he made with the plotly library (https://plot.ly/) and showed me some work he does in the Shiny framwork (https://shiny.rstudio.com/)
Presented my app! Showed off how much I learned in such a short amount of time and proved that I am capable of learning new things and I am a programmer/web-developer/dev etc. So excited to keep learning. Practice everyday! Learn more!
added vue2filters to sort my styles in reverse so the most recent style appears on top -https://github.com/freearhey/vue2-filters
Practiced presenting my ap (script):
Finding the clothes for all the right occasions and even every day can be an overwhelming process. My app shopdream allows you to find your favorite new items both digitally and physically at the click of a button.
- with a backend built in ruby on rails, I created an API that integrates with my frontend in vue.js via axios.
- I built the CSS with Materializecss components
- this is what a user sees when they log in. They have a repository of styles that they have favorited and then for inspiration they can use the integrated instawidget.
- You can add a style via url, upload an image that stores in active storage. Once it uploads you can tag the items and then start shopping!
- By clicking the find nearby my app is making a web request to the Goodzer API to find the item nearby. It's also showing your location via mapbox
- by clicking the find online it's showing all the items with the item tag term in the ASOS api (my favorite store!)
- There's also an admin page that shows the most popular tags
Version 2 will have more features to report on via the admin tag. I also created the first part of the chrome extension.
Adding a chrome extension to app with these 2 tutorials https://www.sitepoint.com/create-chrome-extension-10-minutes-flat/ https://lifehacker.com/5857721/how-to-build-a-chrome-extension
Code to get item_tags to show up in the materialize chips
<div>
<div v-for="item_tag in style.item_tags "class="chip">
{{ item_tag.name }} <i class="close material-icons">close</i>
</div>
</div>
Embed instragram components into app using instawidget: https://instawidget.net/ Added chart.js chart to admin dashboard to see what tags are most commonly used and tagged - https://vue-chartjs.org/guide/
Starter Template for vuejs chart.js component for future projects
<div class="home"><canvas id="myChart"></canvas></div>
</template>
<style></style>
<script>
import Chart from "chart.js";
export default {
data: function() {
return {
message: "Welcome to Vue.js!"
};
},
created: function() {},
method: function() {},
mounted: function() {
var ctx = document.getElementById("myChart").getContext("2d");
var chart = new Chart(ctx, {
// The type of chart we want to create
type: "line",
// The data for our dataset
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
backgroundColor: "rgb(255, 99, 132)",
borderColor: "rgb(255, 99, 132)",
data: [0, 10, 5, 2, 20, 30, 45]
}
]
},
// Configuration options go here
options: {}
});
},
computed: {}
};
</script>```
Implemented the javascript components in materializecss Add map mark to mapbox
Looked into how to make my app look like instragram using materializzcss.Polish a lot of the formatting and made it looks like an actual prototype. Getting my app ready to demo. Prioritzed and updated my trello with what I still have to do by the deadline.
Experimented with mapbox markers in the app researched themes for my shop.dream prototype, looked into installing a theme, looked into https://www.httrack.com/
researched simple AI and/or machine learning options to incorporate into my app
Sinatra backend framework How is it similar to rails? What's different? Designed to be very lightweight Some people refer to it as a microframework
Tutorial to learn Sinatra: https://x-team.com/blog/how-to-create-a-ruby-api-with-sinatra/
Build a notes app with React - differences between vue and react? vuejs is a progressive framework, react gives you everything right upfront but forces you to have a clear architecture
(react native is for IOS and Android apps) .
Regex http://rubular.com/
What's next after bootcamp? Get better at what I already know. There is so much out there to learn and it can be very overwhelming but once you have the basics you can practice that and learn 1-2 languages a year. Learn python, learn C, Look into some functional languages (elixir, clojure).
Worked on a team to make a Resume App for Actualize students. My team of 3 built the backend, included routes, data, cors.rb, gems, etc. Chatted with front end teams to understand needs and desire
Practiced creating branches, pulling and pushing to a shared repository
Monolith - Sometimes an app is made up of several different apps within the larger app. Everything exist together and within the same app. it's possible for someone to write bad code and the entire website can go down
Microservices - Each app/function is it's own application and broken up.
- Pros: One feature might not impact another page
- Cons: harder to share code, helper functions, complicated management, different databases
Individual apps with shared databases
Working on a team
Contribute to the same code base via git and github
You can make changes on your own device but when you try to upload to github if someone changed something between the time you opened it and pushed you will not be able to
git pull origin master
--> grabbing the version that's the master on github and pull it onto the branch that's on your computer (I want the changes the are online)
- Merge conflict: If 2 changes are on the same line (git will paste both versions of your code into your app. You will then have the option to fix it and then you can move on)
- Never edit commit history! Never push to master when working on a team!
git branch add-new-feature
- by default you don't know what branch you are in
git branch
will share what branch you are ingit checkout add-new-feature
- After you make your code updates and test
git push origin add-new-feature
- You can only switch back and fourth between branches if you've committed your changes
- You SHOULD delete your branches once you are done with it
git branch -D add-new-feature
Started reading through: Cracking the Coding Interview: https://github.com/jwang5675/ctci/blob/master/Cracking%20the%20Coding%20Interview%206th%20Edition.pdf
Binary Search Tree - the left node is less than the root node which is less than the right node. Aft each operation you chop off half of the nodes. This makes finding something pretty quickly.
If child is the same as the root it must be to the left
Traversing - going through the tree Inorder - left, than current than right(most common) Preorder - visit root, left than right Postorder - left, than right, than first
Test Driven Development write tests as you write your code
- Write a test without writing codes (this is what I want my code to do)
- Make the code work
- Eliminate redundancy (refactor)
Ensures that you have good test and allows you to write your code in small tiny chunks
Made a change machine. Started by making a penny machine, then nickel machine, than dime, then quarter machine
Test for my CRUD actions gem 'rspec-rails' integration test
Automatic Test index, create, show, destroy, for each one - TDD style: you would write this before you write your models, controllers, views
Tutorial to make a rails backend app where I write the tests before I write the code
Rails API activestorage Saving files is different than saving strings. You display the path that directs it
Testing writing code to test your code so that you can see if your new code broke anything Not spending the time to write the tests will hurt you in the end. This is a documentation of how this code is supposed to work
I expect something to equal something I expect something else to crash
For ruby install rspec gem (to get fancy error messages in the terminal) rbenv rehash
Then require "rspec" in case
RSpec.describe
rspec can be called a DSL (Domain specific language). It still ruby but looks like it's own language
Write the test, run the code, if the test crashes, fix the error as it's described
Another language is minispec
For a rails app, add gem 'rspec-rails', '~> 3.8'
to the development, test groups in the Gemfile. then run the command rails generate rspec:install
*The tests use a different database, not your development data base. When testing you need to run everything from scratch
reference for how you can reference time in ruby: https://stackoverflow.com/questions/4654457/how-to-add-10-days-to-current-time-in-rails
mapbox js library
mounted function this runs after the HTML has been placed on the page as opposed to created method which run when the page is created mounted: function() { //put code for library in here }
Tons of libraries have a jquery dependency but you can use this page to reference this page https://github.com/nefe/You-Dont-Need-jQuery
Practiced looking into libraries and running the hello world https://www.javascripting.com/
Filters items in vue js using a library vs writing all the code from scratch. This rebuilds the page as you type without changing any code
filterBy syntax
v-for="recipe in filterBy(recipes, nameFilter, 'title')"
npm install vue2-filters --save ``import Vue from 'vue' import Vue2Filters from 'vue2-filters'
Vue.use(Vue2Filters)``
more info: https://github.com/freearhey/vue2-filters
Use the datalist HTML tag and use a v-for loop to write all the options for me as I type them into search
<input type="text" v-model="searchFilter" list="names"> <datalist id="names"> <option v-for="product in products">{{ product.name }}</option> </datalist>
buttons to search by filters
build the todoMVC app in vuejs from scratch
Installing a theme to make my app look pretty
don't delete this syntax <div id="app"></div>
or </div> <router-view/> </div>
Testing my routes, controller and views in insomnia for my capstone. Building a controller to work with some APIs
Go to a link with only the information for a certain item in your database
<a v-bind:href"'/#/products/' + product.id" class="btn btn-primary">Go Somewhere</a>
this.$route.params.id
Do everything on one page with a model option (pop up on the page instead of going somewhere) bootstrap modal
how to clone an app
git clone https://github.com/[url for app] cd blog-backend-app bundle install rails db:create rails db:migrate rails db:seed rails server
tools for single page web application using javascript and vuejs
show the errors in the console using
.catch(function(error) { console.log(error.response); }
Add inputs with buttons and have the new input display on the page without refreshing or going to a new page
Authentication in the front end
<p v-if="person.bioVisible">{{ person.bio }}</p>
(only display this tag if the bioVisible = true)
make web request from vuejs to backend
Install axios in the terminal:
npm install axios --save
Require axios in your Home.vue JavaScript:
var axios = require("axios");
Make a web request in the created function:
created: function() { axios.get("http://localhost:3000/api/products").then(function(response) { console.log(response.data); }); },
- cors.rb configuration that allows webrequests from backend to frontend. This goes in the rails app config/intializers
- In gem file add the gem => gem 'rack-cors', require: 'rack/cors'
- kill server and then bundle install
- Run server and qc that the data has come through in the console
Syntax for looping through photos/images to display
<img class="card-img-top v-bind:src="product.image
Where does everything go?
- Home.vue - html for jumbotron
- index.html -
- App.vue -
vue.js https://vuejs.org/v2/guide/ vue CLI tool anything inside the {{ is javascript code }} vue directive v-model="message"
Heroku service that will host a rails app
- add your app to heroku
- add to heroku's database
modern javascript
Sample steps for requiring a library variable in your js file. Getting packages to work in js. JS is a language that doesn't do this.
- momentjs.com
- npm init - using node tools to do what we want it to do (node is for the browser)
- npm install moment --save
- module bundler - a hack becasue js can't do what I want to it use. A file to that allows you to use the require keyword in js.
- webpack a tool that analyizes my file and decides if my code has the variable that it needs. It depends on on a lot of 6. other packages to install
- npm webpack webpack-cli --save -dev
- Now I can say let moment = require("moment");
- HTML file should have <script src="dist/main.js"></script>
- No longer need to touch the HTML file (yay!)
- You always have rerun the command ./node_modules/.bin/webpack index.js --mode-development
- Add another package via the command line.
- add let newpackage = require("newpackage");
- Rerun the command ./node_modules/.bin/webpack index.js --mode-development
- webpack.config.js file with this code:
mode: 'development',
entry: './index.js',
output: {
filename: 'main.js',
publicPath: 'dist'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
};
Use webpack to minify your javascript (makes it as small as possible) webpack is buildstep babble analyze code and replace it with the old version of syntax. Transpile it into the old versison so that every browser can understand
Install babble npm install @babel/core @babel/preset-env babel-loader --save-dev
Now - the webpack command gets smaller! ./node_modules/.bin/webpack
New javascript features to try and practice https://babeljs.io/docs/en/learn
Peter's blog explaining it - https://medium.com/the-node-js-collection/modern-javascript-explained-for-dinosaurs-f695e9747b70 script a series of command that you can run in bulk
Express framework to create a backend
defer key word .appendChild() (this is a paste) .content.cloneNode(true) (this is a copy)
For example, recipeContainer.appendChild(recipeTemplate.content.cloneNode(true)); then copy it as many times as you want it to display command shift r - clear cache and refresh the page sidenote - many programming languages are written in english. Many programmers have to learn english in order to be developer
web requests in javascript(ajax) axios library https://github.com/axios/axios axios.get axios.post load before js file so you can use it axios.get("http://localhost:3000/api/products").then(function(response) { let product = response.data; console.log("the products are", products); });
Timing
hacky way of doing it setTimeout(function() { console.log("this is first"); }, 2000);
setTimeout(function() { console.log("this is second"); }, 4000);
setTimeout(function() { console.log("this is third"); }, 6000);
pyramid of doom way
setTimeout(function() { console.log("first, now wait 2 seconds"); setTimeout(function() { console.log("second, now wait another 2 seconds"); setTimeout(function() { console.log("now, here's the 3rd"); }, 2000); }, 2000); }, 2000);
HTML is static but javascript can be written within the HTML and then when it interacts with the browser it can change (HTML DOM Event objects)
- onmousedown
- hoover
- onkeydown
- mousemove
- https://www.w3schools.com/jsref/dom_obj_event.asp Every element in HTML has a class, id, etc. We're deciding whether or not we want to use it.
onmousemove="doSomething(event)">Alexander Hamilton
function doSomething(event) { console.log(event); }
Prints in the console => MouseEvent {isTrusted: true, screenX: 213, screenY: 155, clientX: 200, clientY: 35, …}
Find something on the page -
- .querySelector allows you to write CSS queries
- .getElementbyId
- .getElementbyClass
.querySelectorAll('p') - an array p tags -> you can loop through the array to add something to each tag
Between innerText and classList you can update and change most styles in javascript via CSS
hidden class
this keyword
todomvc.com - a way to test out if you can do something in an new js framework
Framework vs a library - code that's already written for you to use D3 library Highcharts library javascripting.com ! tab $ stands for a library called jquery
bootstrap: a way to use CSS via HTML to make your website look pretty with very little effort. Great for a prototype. Grid via
Materializecss.com - another framework
Moral of the story - css is not something I need to master. As long as I understand how to read documentation and practice I will be able to to use it successfully.
media queries responsive design css At this point the css breaks from the norm and shows something for mobile or smaller browser @media(max-width:960px) { body { - remove floats - header will change } } chrome dev tools
Looking into API to make shopdream app wireframed, created models via spreadsheet, discuss MVP (minimal viable product)
The relationship between the new action and create action
The relationship between the edit action and update action (when you hit submit, it routes to the update route)
The browser doesn't understand 'patch' or 'delete' you must include this code:<input type ="hidden" name = "_method" value="patch">
application.html.erb - anything that exists on every page will live here (navigation bar, footers, logo)
<%= yield %>
- all your HTML will be in here
data-method="delete"
send a delete request in the browser in rails
Practice making API apps - Trivia app, sunrise app
Some more APIs to practice with - https://github.com/toddmotto/public-apis
create a form in HTML
form action and input tag (type,name,value)
html.erb
<%=
vs <%
How to integrate APIs into your own apps
apikey
OAuth
Add apikey as environment variable on your computer
- Add Gem called figaro
- kill server run bundle install
- bundle exac figaro install a. application.yml and adds it to your gitignore
- put apikey key in application.yml (no quotes)
- Kill server and run it again
- use variable
ENV["NEWS_API_KEY]
instead of the API key
2 week sprints building a shopping card business logic should exist in the model (skinny controller)
methods worth learning and being very familiar
.map .select .reduce
has_many/has_many relationship
join table
SELECT * FROM products JOIN categorie_products ON products.id = category_products.products_id JOIN categories ON categories.id = category_products.category_id;
Manually do this in ruby =>
def products result = [] category_product.each do |category_product| result << category_product.product end return result end end
OR
category_products.map {|category_product| category_product.product} return result
(What do you want to do to each category_product? Show the category_product.product for each category_product.)
Rails can do this by usinghas_many :categories, through: :category_products
MOB programming
before_action :authenicate_admin, except: [:index, :show]
one-way encrypted passwords through bcrypt .
Authentication .
cookies vs json web tokens .
signing up - creating a user .
logging in - creating a json web token .
has_secure_password
.
rescue
keyword
Working with multiple models in my products app.
Creating methods so that they can work together
shortcuts: belongs_to :supplier
has_many :products
Understanding error codes, status options .
validation rules when adding to the database .
if/else statements surrounding error messages .
render json: {errors: @product.errors.full_messages}, status: 422
.
database normalization . primary key, foreign key . has_many belongs_to relationship .
Data Structures:
linear vs binary search .
Big O Notation .
Learned SQL, a programming language that gets data from a database . practice with Postico . Use SQL to grab data from database and add it to contacts app .
Make updates to database via a migration .
Learned about jbuilder partials .
json.partial! "product.json.jbuilder", product: @product
first RESTful crud app complete
Any POST request will crash until you add the line protect_from_forgery with: :null_session
in the ApplicationController
Model/view/controller . CRUD apps . migrate to postgresql .
first rails app - generate a fortune and lotto number
Insomnia . installing gems . Weather app using yahoo weather API Terminal app using dictionary API
Module vs Inheritance .
require keyword .
practice whiteboarding
peer coding .
Rubocop - tells me what is wrong with my ruby syntax . Homebrew - allows me to download tools to the mac through the terminal . Dry vs Wet code . input a hash into a method . inheritance . super
Version control . git