I can't seem to figure out where I'm going wrong in my code to cause my app to not completely render the transactions. I double-checked my variables in both mySQL & in React, so it's not a variable issue. I'm not sure if the error lies on the front-end (React) side, but I'm fairly sure that it does.
Here is my code for TransactionsList:
function TransactionsList() {
const [transactions, setTransactions] = useState([]);
useEffect(() => {
let username = AuthenticationService.getLoggedInUserName();
TransactionDataService.retrieveAllTransactions(
username
).then((transactions) => setTransactions([transactions]));
}, []);
return (
<CardColumns style={{ padding: "20px" }}>
{transactions.map((transaction) => (
<TransactionCard transaction={transaction} />
))}
</CardColumns>
);
}
Here is my code for TransactionCard:
const username = AuthenticationService.getLoggedInUserName();
TransactionDataService.retrieveTransaction(username, useState.id).then(
(response) =>
useState({
accountName: response.data.accountName,
transactionDate: response.data.transactionDate,
transactionType: response.data.transactionType,
depositCategory: response.data.depositCategory,
withdrawalCategory: response.data.withdrawalCategory,
transactionAmount: response.data.transactionAmount,
notes: response.data.notes,
})
);
export default function TransactionCard(props) {
const classes = useStyles();
const [expanded, setExpanded] = useState(false);
const handleExpandClick = () => {
setExpanded(!expanded);
};
const { transaction } = props;
// const { data: transactions } = useSWR((url) =>
// fetch(url).then((_) => _.json())
// );
const getTransactions = (url) => fetch(url).then((_) => _.json());
const { data: transactions } = useSWR(
`http://localhost:8080/jpa/users/${username}/transactions`,
getTransactions
);
useEffect(() => {
console.log(transactions);
}, [transactions]);
function handleEdit(id) {
console.log("handle edit");
alert("you clicked edit");
}
function handleDelete(id) {
console.log("handle delete");
}
return (
<>
<Card className={classes.card}>
<center>
<CardHeader tag="h3">{transaction.accountName}</CardHeader>
<CardText>{transaction.transactionType}</CardText>
<CardText>
{moment.utc(transaction.transactionDate).format("MMM-DD-YYYY")}
</CardText>
<CardText>{transaction.depositCategory}</CardText>
<CardText>{transaction.withdrawalCategory}</CardText>
<CardText>{"$" + parseFloat(transaction.transactionAmount)}</CardText>
</center>
Here is the relevant Java code:
#GetMapping("/jpa/users/{username}/transactions")
public List<Transaction> getAllTransactions(#PathVariable String username) {
return transactionJpaRepository.findByUsername(username);
}
Here are my findings from when I did a curl:
StatusCode : 200
StatusDescription :
Content : [{"id":200
1,"usernam
e":"Tim","
accountNam
e":"BOA","
transactio
nDate":"20
21-03-13T0
2:19:33.00
0+00:00","
transactio
nType":"de
posit","de
positCateg
ory":"payr
oll","with
drawalCate
gory":null
,"transact
ionAmount"
...
RawContent : HTTP/1.1
200
Vary: Orig
in,Access-
Control-Re
quest-Meth
od,Access-
Control-Re
quest-Head
ers
Transfer-E
ncoding:
chunked
Keep-Alive
:
timeout=60
Connection
:
keep-alive
Content-Ty
pe: applic
ation/json
Da...
Forms : {}
Headers : {[Vary, Or
igin,Acces
s-Control-
Request-Me
thod,Acces
s-Control-
Request-He
aders], [T
ransfer-En
coding,
chunked],
[Keep-Aliv
e, timeout
=60], [Con
nection, k
eep-alive]
...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : mshtml.HTM
LDocumentC
lass
RawContentLength : 1387
Here is my POJO:
#Entity
public class Transaction {
#Id
#GeneratedValue
private long id;
private String username;
private String accountName;
private Date transactionDate;
private String transactionType;
private String depositCategory;
private String withdrawalCategory;
private double transactionAmount;
private String notes;
protected Transaction() {
}
public Transaction(long id, String username, String accountName, Date transactionDate, String transactionType,
String depositCategory, String withdrawalCategory, double transactionAmount, String notes) {
super();
this.id = id;
this.username = username;
this.accountName = accountName;
this.transactionDate = transactionDate;
this.transactionType = transactionType;
this.depositCategory = depositCategory;
this.withdrawalCategory = withdrawalCategory;
this.transactionAmount = transactionAmount;
this.notes = notes;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public Date getTransactionDate() {
return transactionDate;
}
public void setTransactionDate(Date transactionDate) {
this.transactionDate = transactionDate;
}
public String getTransactionType() {
return transactionType;
}
public void setTransactionType(String transactionType) {
this.transactionType = transactionType;
}
public String getDepositCategory() {
return depositCategory;
}
public void setDepositCategory(String depositCategory) {
this.depositCategory = depositCategory;
}
public String getWithdrawalCategory() {
return withdrawalCategory;
}
public void setWithdrawalCategory(String withdrawalCategory) {
this.withdrawalCategory = withdrawalCategory;
}
public double getTransactionAmount() {
return transactionAmount;
}
public void setTransactionAmount(double transactionAmount) {
this.transactionAmount = transactionAmount;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Transaction other = (Transaction) obj;
if (id != other.id)
return false;
return true;
}
}
Debugging reveals this once I stepped over transactionJpaRepository.findByUsername(username):
"Hibernate: select transactio0_.id as id1_1_, transactio0_.account_name as account_2_1_, transactio0_.deposit_category as deposit_3_1_, transactio0_.notes as notes4_1_, transactio0_.transaction_amount as transact5_1_, transactio0_.transaction_date as transact6_1_, transactio0_.transaction_type as transact7_1_, transactio0_.username as username8_1_, transactio0_.withdrawal_category as withdraw9_1_ from transaction transactio0_ where transactio0_.username=?"
It's a lot of code to follow, but one thing stands out at me when I glance over this code...
You set your state-managed transactions up to be an array of transaction as such:
const [transactions, setTransactions] = useState([]);
Then you clearly have a local object coming back from your TDS promise called "transactions" which I'm guessing would ALSO be an array.
TransactionDataService.retrieveAllTransactions(username)
.then((transactions) => setTransactions([transactions]));
So if that's all true, then your state-driven setTransactions call here is taking your Promise-Returned array and wrapping it into a single-array element...
So your state-driven transactions after this would look like:
transactions = [
[ tx1, tx2, tx3, .... ]
]
In this case, it makes sense that your state-driven transactions object only has one record in it. Although that one-record should be the array of all transactions..
If this is the case, the solution is to fix your setTransactions to NOT have a [] wrapping your promise-returned transactions array.
That said, reading the comments it does sound like curl/back-end needs addressing before you hit this.
I am looking to implement edit book, loan book and return book function and don't know where to begin.
So far I have 4 classes consisting of a Book, Library, LibraryTester and helperutilities class.
package Assignment;
import java.util.Scanner;
public class LibraryTester {
public static void main(String args[]){
Library lib = new Library(HelperUtilities.generateBooks());
Scanner sc = new Scanner(System.in);
displayMenu(lib, sc);
}
public static void displayMenu(Library i, Scanner s) {
System.out.println("--- Library Menu ---");
System.out.println("---(1) Display Books ---");
System.out.println("---(2) Add Book ---");
System.out.println("---(3) Remove Book ---");
System.out.println("---(4) Edit Book ---");
System.out.println("---(5) Loan Book ---");
System.out.println("---(6) Return Book ---");
System.out.println("---(7) EXIT ---");
So far 1,2 3 and 5 functions work according to the methods I have created in my Library class. I now just need to implement a method for edit book, loan book and return book. Any help would be appreciated, thanks.
library class methods:
package Assignment;
import java.util.ArrayList;
import java.util.Scanner;
public class Library {
private ArrayList<Book> books;
public Library (ArrayList<Book> books){
super();
this.books = books;
}
public ArrayList<Book> getBooks () {
return books;
}
public void setBooks(ArrayList<Book> books){
this.books = books;
}
public void displayBooks()
{
for (int i = 0; i < books.size(); i++) {
System.out.println("ID " +books.get(i).getBookID());
System.out.println("Title "+books.get(i).getTitle());
}
System.out.println("Displayed "+books.size()+" Books");
}
public void addBook(int ID, String title)
{
books.add(new Book(ID,title));
}
public void loaning_A_Book (int bookIndex) {
Book book = books.get(bookIndex);
book.setOn_Loan (true);
}
public void removeBook(int id)
{
boolean successful = false;
for (int i=0;i<books.size();i++)
{
if((int)books.get(i).getBookID()==id)
{
books.remove(i);
System.out.println("Book removal successful");
successful=true;
}
}
if (!successful)
{
System.out.println("Could not remove book id "+id);
}
}
public void editBook(int idToEdit, Scanner s) {
// TODO Auto-generated method stub
}
}
Book class:
package Assignment;
public class Book {
//Instance variables
private int BookID;
private String Title;
private String Author;
private boolean On_Loan;
private int Number_of_Loans;
public Book(int BookID, String Title) {
this.BookID = BookID;
this.Title = Title;
}
//Constructor
public Book(int BookID, String Title, String Author, boolean On_Loan, int Number_of_Loans){
this.BookID = BookID;
this.Title = Title;
this.Author = Author;
this.On_Loan = On_Loan;
this.Number_of_Loans = Number_of_Loans;
}
//Mutator methods
public void setBookID(int BookID){
this.BookID = BookID;
}
public void setTitle(String Title){
this.Title = Title;
}
public void setAuthor(String Author){
this.Author = Author;
}
public void setOn_Loan(boolean On_Loan){
this.On_Loan = On_Loan;
}
public void setNumber_of_Loans(int Number_of_Loans){
this.Number_of_Loans = Number_of_Loans;
}
//Accessor methods
public int getBookID(){
return BookID;
}
public String getTitle(){
return Title;
}
public String getAuthor(){
return Author;
}
public boolean getOn_Loan(){
return On_Loan;
}
public int getNumber_of_Loans(){
return Number_of_Loans;
}
private boolean available;
public void setAvailable(boolean avail){
available = avail;
}
public boolean isAvailable(){
return available;
}
}
Editing a book :
Book book = lib.getBook(bookId);
// edit by making all the text lower-case, for instance
book.setText(book.getText().toLowerCase());
Loaning and returning books :
Book class could have an available attribute
private boolean available;
public void setAvailable(boolean avail){
available = avail;
}
public boolean isAvailable(){
return available;
}
Then for loan :
lib.getBook(bookId).setAvailable(false);
And for return :
lib.getBook(bookId).setAvailable(true);
Of course, Library shouldn't list unavailable books in the Display books part (call isAvailable() and check if it is true).
i get three error message on my BookTest class and it says cannot find symbol on getCode(), getCategory, and calculateTax. how do i fix this? im trying to print these out in a dialog box but these three are the only ones not working.
import javax.swing. JOptionPane;
public class BookTest
{
public static void main(String args[])
{
double charge;
double grandTotal= 0;
String dataArray[][] = {{"NonFiction", "Abraham Lincoln Vampire Hunter","Grahame-Smith","978-0446563079","13.99","Haper","NY","US","Political"},
{"NonFiction", "Frankenstein","Shelley","978-0486282114","7.99","Pearson", "TX","England", "Historical"},
{"Fiction", "Dracula","Stoker","978-0486411095","5.99","Double Day", "CA","4918362"},
{"NonFiction", "Curse of the Wolfman"," Hageman","B00381AKHG","10.59","Harper", "NY","Transylvania","Historical"},
{"Fiction", "The Mummy","Rice","978-0345369949","7.99","Nelson","GA","3879158"}};
Book bookArray[] = new Book[dataArray.length];
int quantityArray[] = {12, 3, 7, 23, 5};
for (int i = 0; i < dataArray.length; i++)
{
if (dataArray[i][0] == "NonFiction")
{
bookArray[i] = new NonFictionBook(dataArray[i][1], dataArray[i][2], dataArray[i][3], Double.parseDouble(dataArray[i][4]),
new Publisher(dataArray[i][5], dataArray[i][6]), dataArray[i][7], dataArray[i][8]);
}
else
{
bookArray[i] = new FictionBook(dataArray[i][1], dataArray[i][2], dataArray[i][3], Double.parseDouble(dataArray[i][4]),
new Publisher(dataArray[i][5], dataArray[i][6]), Integer.parseInt(dataArray[i][7]));
}
}
String msg = "";
for (int i = 0; i < bookArray.length; i++)
{
charge = bookArray[i].calculateTotal(quantityArray[i]);
grandTotal = charge + grandTotal;
msg += String.format("%s %s %d $%.2f $%.2f\n", bookArray[i].getTitle(), bookArray[i].getCategory(), bookArray[i].getCode(), bookArray[i].calculateTax, charge); //this is where i get the 3 error messages. im trying to print all in one dialog box the title, category of the book, charge and tax for each book.
}
msg += String.format("Grand Total $%.2f ", grandTotal);
JOptionPane.showMessageDialog(null, msg);
}
}
**************************************************************
public abstract class Book implements Tax
{
private String title;
private String author;
private String isbn;
private Double price;
private Publisher publisher;
public Book()
{
setTitle("");
setAuthor("");
setIsbn("");
setPrice(0.0);
setPublisher(new Publisher());
}
public Book(String t, String a, String i, double p, Publisher n)
{
setTitle(t);
setAuthor(a);
setIsbn(i);
setPrice(p);
setPublisher(n);
}
public void setTitle(String t)
{
title = t;
}
public String getTitle()
{
return title;
}
public void setAuthor(String a)
{
author = a;
}
public String getAuthor()
{
return author;
}
public void setIsbn(String i)
{
isbn = i;
}
public String getIsbn()
{
return isbn;
}
public void setPrice(double p)
{
price = p;
}
public double getPrice()
{
return price;
}
public void setPublisher(Publisher n)
{
publisher = n;
}
public Publisher getPublisher()
{
return publisher;
}
public abstract double calculateTotal(int quantity);
public double calculateTax(double a)
{
return a * .08;
}
public String toString()
{
return( " Title " + title + " Author " + author + " Isbn " + isbn
+ " Price " + price + " Publisher " + publisher.toString());
}
}
********************************************************
public class NonFictionBook extends Book
{
private String country;
private String category;
public NonFictionBook()
{
super();
setCountry("");
setCategory("");
}
public NonFictionBook(String t, String a, String i, double p, Publisher n, String c, String ca)
{
super(t,a,i,p,n);
setCountry(c);
setCategory(ca);
}
public void setCountry(String c)
{
country = c;
}
public void setCategory(String ca)
{
category = ca;
}
public String getCountry()
{
return country;
}
public String getCategory()
{
return category;
}
public String toStirng()
{
return( super.toString() + "Country " + country + " Category " + category);
}
public double calculateTotal(int quantity)
{
double charge =0;
charge = (quantity * getPrice());
if( country != "US" )
charge += 50;
return charge;
}
}
*********************************************
public class FictionBook extends Book
{
private int code;
public FictionBook()
{
super();
setCode(0);
}
public FictionBook(String t, String a, String i, double p, Publisher n, int c)
{
super(t,a,i,p,n);
setCode(c);
}
public void setCode(int c)
{
code = c;
}
public int getCode()
{
return code;
}
public String toString()
{
return (super.toString() + " Code " + code);
}
public double calculateTotal(int quantity)
{
double charge =0;
charge = (quantity * getPrice());
if (quantity > 5)
charge += 5 * (quantity - 5);
return charge;
}
}
The tree methods are implemented in subclasses of Books. So you have to cast the value to the subclass.
if (bookArray[i] instanceof FictionBook){
FictionBook fb = (FictionBook)bookArray[i];
msg += String.format("%s %s %d $%.2f $%.2f\n", fb.getTitle(), "", fb.getCode(), 0, charge);
}
if (bookArray[i] instanceof NonFictionBook){
NonFictionBook fb = (NonFictionBook)bookArray[i];
msg += String.format("%s %s %d $%.2f $%.2f\n", nfb.getTitle(), nfb.getCategory(), nfb.getCode(), nfb.calculateTax, charge);
}
and so on
Also you have to use equals() for comparing string. Not ==
In the line you get error you try to print fields that are not instances of the Book class but of its subclasses.
You got an array of Books, you iterate on them and try to print the information. But not all the Books have getCode() method (only the fiction books) and only the non fiction books have getCategory() method. So you can't do this for ALL books.
You can change your print depending on the book type or you can make a method in Book class and each subclass can override it that prints the information you have for this class (like the toString method). Then use that in the main class.
And also as pointed in comments test if strings are equal with equals operator and not == or !=
Your array uses the type book:
Book bookArray[] = new Book[dataArray.length];
Later, you add sub-classes into this array, like NonFictionBook. Since code, category etc. are only part of the sub-classes, you cannot access them using the Book array reference.
// won't work because class Book does not have these methods, properties
bookArray[i].getCategory(), bookArray[i].getCode(), bookArray[i].calculateTax
You need to cast the object (based on what type is in the array).
I am new to NDK and JNI. I have a struct which contains 2 uint64_t variables, I want to pass these as an jobject to the java class.
Java class
public class MyClass {
private long mVar1;
private long mVar2;
public MyClass() {
}
public MyClass(final long mVAR1, final long mVar2) {
this.mVar1 = mVar1;
this.mVar2 = mVar2;
}
public long getVar1() {
return this.mVar1;
}
public long getVar2() {
return this.mVar2;
}
}
Here is my JNI
JNIEXPORT jobject JNICALL Java_my_class_getMyClass(JNIEnv * env, jobject jobj) {
clazz = env->FindClass("my/package/test/MyClass");
methodID = env->GetMethodID(clazz, "<init>", "(JJ)V");
return convertMyClass(env, test.getMyClass());
}
Here is the convert
jobject convertMyClass(JNIEnv * env, MyClass myClass) {
jobject jmyclass = env->NewObject(clazz, methodID);
return jmyclass;
}
How can i add arguments to the convertMyClass.
I have a Java program that communicates to a C program. I have written JNI before but my output structure was more simplistic and the C structure just contained doubles/ints and arrays of doubles/ints.
Now my structure contains a substructure (class/subclass) and I don't know how to change the code to access the subclass data/fields.
My C code looked like this but how do I access a value like DefaultFeeAmount if you look at my Java Class below this code....how do I get to the elements within the subclass?
C straightforward....
{
jclass out_rec_cls = jenv->GetObjectClass(ptrTo_out_rec);
jfieldID fldID, fldID2;
jintArray arr;
jdoubleArray darr;
jobjectArray oarr;
jsize len;//,len2;
jint *arrElems;
jdouble *darrElems;
jobject *oarrElems;
int i;
char temp_str[100],temp_str2[10000];
fldID = jenv->GetFieldID(out_rec_cls, "ErrorCode", "I");
if(fldID != NULL)
jenv->SetIntField(ptrTo_out_rec, fldID, out_rec->error_code);
}
Java
class FeeOutput {
public double DefaultFeeAmount;
public double MaximumAmount;
public int FeeID;
public int CompType;
public int Handling;
public int CapType;
public int ProfitType;
public int EffectiveDateMonth;
public int EffectiveDateDay;
public int EffectiveDateYear;
public int VendorBasedFee;
public int DealerRequestedFee;
public int DealerFixedTranFee;
public double FeeAmount;
public int FeeCompliant;
public String FeeName = "";
public FeeOutput() {
}
}
public class VFeeOutput {
public static final int NUM_FEES = 100;
public FeeOutput[] FeeStruct = new FeeOutput[NUM_FEES];
public int ErrorCode;
public String ErrorString = "";
public String Version = "";
public VFeeOutput() {
}
}
As a wide-spread Java convention tip, please start variable names with lower case. Here how you can access "struct" fields in Java.
public class VFeeOutput {
public static final int NUM_FEES = 100;
public FeeOutput[] FeeStruct = new FeeOutput[NUM_FEES];
public int ErrorCode;
public String ErrorString = "";
public String Version = "";
public VFeeOutput() {
}
private void loopThoughtFeeOutput() {
for(FeeOutput feeOutput : FeeStruct) {
feeOutput.CompType = ...;
}
// or
for(int i = 0; i < FeeStruct.length; i++) {
FeeStruct[0].CompType = ...;
}
}
}