Skip to content
This repository has been archived by the owner on Apr 1, 2024. It is now read-only.

Sabrina/customer info model #27

Merged
merged 4 commits into from Mar 23, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,52 @@
package com.fullstorydev.shoppedemo.data;

import com.fullstorydev.shoppedemo.utilities.Constants;

import java.util.HashMap;

public class CustomerInfo {
private HashMap<String,String> strMap;
private HashMap<String,Integer> intMap;

CustomerInfo(){
// all key-value pairs available for USER_INFO_STRING_KEYS
strMap = new HashMap<>();
// all key-value pairs available for USER_INFO_INTEGER_KEYS
intMap = new HashMap<>();
}

// all available user info keys are managed by Constants.USER_INFO_STRING_KEYS
boolean putValue(String key, String val){
for(String k: Constants.USER_INFO_STRING_KEYS){
if(k.equals(key)) {
strMap.put(key, val);
return true;
}
}
return false;
}

// all available user info keys are managed by Constants.USER_INFO_INTEGER_KEYS
boolean putValue(String key, Integer val){
for(String k: Constants.USER_INFO_INTEGER_KEYS){
if(k.equals(key)) {
intMap.put(key, val);
return true;
}
}
return false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why use hash maps like this rather than use getters and setters?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great question and exactly why I've been working on this for this long.
The problem with having specific setters is that all of those methods need to propagate through model->repository->view model and finally used by the view via binding. It gets harder when using encapsulate the whole form into one LiveData, you'd have to make it "property aware". It would potentially make the code more readable but also likely make it a harder to maintain when fields need to be added/modified. I wanted to use the constants as a "catalog" of the fields and have them organized.
Having said that I realize form validation might be a challenge this way.
I have leaned against binding onTextChanged handler to persist data as user input their info. Feels like unnecessary calls to update data on each key stroke. But maybe that is the solution after all... WDYT

https://developer.android.com/topic/libraries/data-binding/two-way
https://medium.com/androiddevelopers/viewmodels-persistence-onsaveinstancestate-restoring-ui-state-and-loaders-fc7cc4a6c090

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think erring on the side of readability is the right choice. I'm not sure what the consequences are of persisting data as it is entered. I skimmed through those articles and it seems like two-way binding on ViewModels is once approach that Android recommends, though having to verify that values have actually changed at the risk of incurring an infinite loop is a little freaky. I always prefer unidirectional binding for these types of reasons.

I'll go ahead and approve.


// public getters for data binding
public String getFirstName(){ return strMap.get(Constants.FIRST_NAME); }
public String getLastName() { return strMap.get(Constants.LAST_NAME); }
public String getAddress1() { return strMap.get(Constants.ADDRESS_1); }
public String getAddress2() { return strMap.get(Constants.ADDRESS_2); }
public String getCity() { return strMap.get(Constants.CITY); }
public Integer getState() { return intMap.get(Constants.STATE); }
public String getZip() { return strMap.get(Constants.ZIP); }
public String getCreditCardNumber() { return strMap.get(Constants.CREDIT_CARD_NUMBER); }
public Integer getExpirationMonth() { return intMap.get(Constants.EXPIRATION_MONTH); }
public Integer getExpirationYear() { return intMap.get(Constants.EXPIRATION_YEAR); }
public String getSecurityCode() { return strMap.get(Constants.SECURITY_CODE); }
}
@@ -0,0 +1,103 @@
package com.fullstorydev.shoppedemo.utilities;

import java.util.Calendar;

public class Constants {
private static final String[] States={
"AL",
"AK",
"AZ",
"AR",
"CA",
"CO",
"CT",
"DE",
"FL",
"GA",
"HI",
"ID",
"IL",
"IN",
"IA",
"KS",
"KY",
"LA",
"ME",
"MD",
"MA",
"MI",
"MN",
"MS",
"MO",
"MT",
"NE",
"NV",
"NH",
"NJ",
"NM",
"NY",
"NC",
"ND",
"OH",
"OK",
"OR",
"PA",
"RI",
"SC",
"SD",
"TN",
"TX",
"UT",
"VT",
"VA",
"WA",
"WV",
"WI",
"WY"
};

static public String[] getStates(){ return States; }

static public boolean isValidState(int state) {
if(state < 0 || state > States.length) return false;
return true;
}

// generate all valid year selection for credit card expiration year. range: now ~ +10 years
static public Integer[] getYears() {
int numYears = 10;
int currentYear = Calendar.getInstance().get(Calendar.YEAR);

Integer[] years = new Integer[numYears];
for(int i=0;i<numYears;i++){
years[i] = currentYear + i;
}
return years;
}

// generate all valid month selection for credit card expiration year. range: 1~12
static public Integer[] getMonths() {
int numMonth = 12;
Integer[] months = new Integer[12];
for(int i=0;i<numMonth;i++){
sabrina-li marked this conversation as resolved.
Show resolved Hide resolved
months[i] = i+1;
}
return months;
}

// all available user info fields
public static final String FIRST_NAME = "firstName";
public static final String LAST_NAME = "lastName";
public static final String ADDRESS_1 = "address1";
public static final String ADDRESS_2 = "address2";
public static final String CITY = "city";
public static final String STATE = "state";
public static final String ZIP = "zip";
public static final String CREDIT_CARD_NUMBER = "creditCardNumber";
public static final String EXPIRATION_MONTH = "expirationMonth";
public static final String EXPIRATION_YEAR = "expirationYear";
public static final String SECURITY_CODE = "securityCode";
public static final String[] USER_INFO_STRING_KEYS = { FIRST_NAME, LAST_NAME, ADDRESS_1, ADDRESS_2, CITY, ZIP, CREDIT_CARD_NUMBER, SECURITY_CODE };
public static final String[] USER_INFO_INTEGER_KEYS = { EXPIRATION_MONTH, EXPIRATION_YEAR, STATE };

}