For the function getAllcars, I wanted to return a struct array. However, it seems this cannot be done (yet). I attempted a workaround by using a recursive function which returns the details of each Customer one by one; the uint getCarsID starts at zero and is incremented with each loop until it is greater than the number of customers in the array (CarOwnerID), at which point it resets the value of getCarsID to zero so that it can be used again later.
Remix accepts this code when compiled and doesn't raise any issues when I execute it, but it doesn't actually return anything. I half-expected this not to work anyways, but I can't put my finger on why. Did I miss something? And if this cannot be done, is there another way to return all of the information in a struct array at once?
// <----------------------- END MEMBERS ----------------------->
struct Customer {
address addr;
string custname;
string color;
string make;
uint16 year;
string license;
}
// < -------------------------- CARS -------------------------- >
uint8 CarOwnerID;
Customer[] public carowners;
mapping(address => uint8) addressIndex;
mapping(string => uint8) licenseIndex;
function newCarOwner(address _address, string _custname, string _color, string _make, uint16 _year, string _license) onlyMember public {
carowners.push(Customer(_address, _custname, _color, _make, _year, _license));
addressIndex[_address] = CarOwnerID; //Testing to see if we can switch what
CarOwnerID = licenseIndex[_license]; //is on each side of the equation.
CarOwnerID ++;
}
function getCarByAdd(address _address) public view returns(address, string, string, string, uint16, string) { // We must return each element in the struct
return ( // because we cannot return an entire struct (for now)
carowners[addressIndex[_address]].addr, // Notice - when returning elements of an array, use "," after each
carowners[addressIndex[_address]].custname, // element instead of ";", and put nothing after the last element.
carowners[addressIndex[_address]].color,
carowners[addressIndex[_address]].make,
carowners[addressIndex[_address]].year,
carowners[addressIndex[_address]].license
);
}
function getCarByLic(string _license) public view returns(address, string, string, string, uint16, string) {
return (
carowners[licenseIndex[_license]].addr, // While we can return whole arrays (ex. return carowners[];), and we can return specific indexed items
carowners[licenseIndex[_license]].custname, // such as uint returning array[3], array[4], etc., we cannot return a specific item if it is a struct.
carowners[licenseIndex[_license]].color, // AKA if array[3] is a struct, we cannot say return array[3], but must say "return array[3].param1, array{3].param2, etc.
carowners[licenseIndex[_license]].make, // See DOC1 in NOTES
carowners[licenseIndex[_license]].year,
carowners[licenseIndex[_license]].license
);
}
uint8 public getCarsID;
function getAllCars() public returns(address, string, string, string, uint16, string) {
return (
carowners[getCarsID].addr,
carowners[getCarsID].custname,
carowners[getCarsID].color,
carowners[getCarsID].make,
carowners[getCarsID].year,
carowners[getCarsID].license
);
getCarsID ++;
if (getCarsID <= CarOwnerID) getAllCars;
else (getCarsID = 0);
}
function countCars() public view returns (uint) {
return carowners.length;
}
return
statement is unreachable. Also, you do not want to use, what will default to a storage variable (getCarsID
), as your way to index a loop. That is very costly gas wise. – ReyHaynes Jun 3 '18 at 5:26