Passing Data between Apps

I'm making an app that calls up additional apps for input.
I've managed to do this successfully when all the variables are created in the second app.
However, I now need to make an app that has a drop down input that draws its items from the main app.
The guide on multi window apps is very good on showing how to "pass down" data, but not on "passing up" data.
I really need some help on this!

 Risposta accettata

Adam Danz
Adam Danz il 7 Lug 2020
Modificato: Adam Danz il 15 Mar 2022
The documentation you mentioned, Creating Multiwindow Apps in App Designer, shows how to pass data both ways. If there's a section that is unclear, I'd be glad to help out with that step.
The main idea is to get access to the app handle for both apps. This answer also reviews some strategies.
Update: Here's a general idea of how to access external app data within a second app.
Step 1: Set up the Payroll app to receive one additional input which will be the app handle to the app that calls Payroll.
function startupFcn(app, callerApp)
Step 2: Within the Payroll app, delcare the callerApp as a private property.
It will look something like this
properties (access = private)
callerApp % handle to caller app
end
Step 3: Define callerApp in the Payroll startupFcn
function startupFcn(app, callerApp)
app.callerApp = callerApp;
end
Step 4: Access the callerApp data anywhere within your app.
function updatePayroll(app)
app.callerApp.PayDate
app.callerApp.PayName
end

25 Commenti

Eli Blumen
Eli Blumen il 8 Lug 2020
I was getting a little confused on how/if I needed to declare input arguments for the main app in order for it to pass data to the secondary app.
The link you posted is very helpful and seems to indicate that I can just call the handle for one of the apps to access its data.
Am I correct in understanding, that if a variable or function in one app is publicly declared, I can just call it? Otherwise, how would I call that variable up using the handle method?
That's correct.
If you open app2 in app1,
app2 = mySecondApp;
Now App1 has all the handles to app2.
If you need app1 handles within app2, you can use one of the examples in the 2nd link in my answer.
Eli Blumen
Eli Blumen il 8 Lug 2020
Thanks!
Eli Blumen's answer moved here as a comment.
Would this be a correct example for calling app1 from app2? Because I keep getting an error of not having enough input arguments.
function startupFcn(app, mainapp, PayDate, EmployeeName)
app.CallingApp = mainapp;
app.DateEditField.Value = Date;
app.EmployeeDropDown.Items = {mainapp.LastName,mainapp.FirstName};
app.EmployeeDropDown.Value = EmployeeName;
Adam Danz
Adam Danz il 9 Lug 2020
I need to see the complete error message.
Do your app have inputs?
Have you defined CallingApp as a property?
The error in your answer below shows that "Payroll" has "too many input arguments". In your previous comment, you mentioned that the error was "not enough input arguments".
It looks like you're proving 3 inputs.
Payroll(app,app.PayDate,app.PayName)
How many inputs does Payroll have? Can you share the line that defines Payroll?
Error using Payroll
Too many input arguments.
Error in TE566/PayEmployeeButtonPushed (line 347)
app.PayrollApp = Payroll(app,app.PayDate,app.PayName);
Error using matlab.ui.control.internal.controller.ComponentController/executeUserCallback (line 382)
Error while evaluating Button PrivateButtonPushedFcn.
CallingApp was defined as a property for this app (app3), I had also defined it for use in app2 - where it works fine.
The inputs for the app are a drop down selector, which reads data stored in the main app, and an edit field for the date.
Adam Danz
Adam Danz il 10 Lug 2020
Is Payroll the app or is it a function?
If you're passing inputs into an app, see this page of the documentation.
If Payroll is a function, please share the function definition.
Payroll is the name of the called app. It would be the 3rd app.
It is supposed to take as an imput, a property (array) from the main app to use as items in a drop down selector.
It is supposed to output the value of that selector and an edit field.
Properties from first app I want to input into the third app:
EmployeeLastName = {'Doe'};
EmployeeFirstName = {'John'};
Current startup function of third app:
function startupFcn(app, mainapp, PayDate, EmployeeName)
app.CallingApp = mainapp;
app.DateEditField.Value = Date;
app.EmployeeDropDown.Items = {mainapp.LastName,mainapp.FirstName};
app.EmployeeDropDown.Value = EmployeeName;
end
Current passing function of third app in main app:
function updatePayroll(app, PayDate, EmployeeName)
app.PayDate = PayDate;
app.PayName = EmployeeName;
app.DatePaid = [app.DatePaid;app.PayDate];
app.Employee = [app.Employee;app.PayName];
app.MSL = [app.MSL;app.MonthlySalary];
app.BL = [app.BL;app.Bounce];
app.WFL = [app.WFL;app.Withholding_Federal];
app.WSL = [app.WSL;app.Withholding_State];
app.WSSNL = [app.WSSNL;app.Withholding_SocialSecurity];
app.WML = [app.WML;app.Withholding_Medicare];
app.WL = [app.WL;app.Withholding];
app.DL = [app.DL;app.Disbursment];
app.Withholding_Total = sum(app.Withholding);
app.Disbursment_Total = sum(app.Disbursment);
app.PayEmployeeButton.Enable = 'on';
end
Current calling function of third app in main app:
function PayEmployeeButtonPushed(app, event)
app.PayEmployeeButton.Enable = 'off';
app.PayrollApp = Payroll(app,app.PayDate,app.PayName);
end
I am a little confused by the documentation you referenced, because when I had previously called an app successfully before - its startup function had only declared input values generated by itself.
function startupFcn(app, mainapp, NewLastName, NewFirstName, NewAddressLine1, NewAddressLine2, NewCity, NewState, NewZip, NewSSN, NewYearlySalary)
app.CallingApp = mainapp;
app.LastNameEditField.Value = NewLastName;
app.FirstNameEditField.Value = NewFirstName;
app.AddressLine1EditField.Value = NewAddressLine1;
app.AddressLine2EditField.Value = NewAddressLine2;
app.CityEditField.Value = NewCity;
app.StateEditField.Value = NewState;
app.ZipEditField.Value = NewZip;
app.SSNEditField.Value = NewSSN;
app.YearlySalaryEditField.Value = NewYearlySalary;
end
When referenced in the main app, its passing function looked like this:
function updateEmployees(app, NewLastName, NewFirstName, NewAddressLine1, NewAddressLine2, NewCity, NewState, NewZip, NewSSN, NewYearlySalary)
app.NewLastName = NewLastName;
app.NewFirstName = NewFirstName;
app.NewAddressLine1 = NewAddressLine1;
app.NewAddressLine2 = NewAddressLine2;
app.NewCity = NewCity;
app.NewState = NewState;
app.NewZip = NewZip;
app.NewSSN = NewSSN;
app.NewYearlySalary = NewYearlySalary;
app.EmployeeLastName = [app.EmployeeLastName;app.NewLastName];
app.EmployeeFirstName = [app.EmployeeFirstName;app.NewFirstName];
app.EmployeeAddressLine1 = [app.EmployeeAddressLine1;NewAddressLine1];
app.EmployeeAddressLine2 = [app.EmployeeAddressLine2;app.NewAddressLine2];
app.EmployeeCity = [app.EmployeeCity;app.NewCity];
app.EmployeeState = [app.EmployeeState;app.NewState];
app.EmployeeZip = [app.EmployeeZip;app.NewZip];
app.SocialSecurityNumber = [app.SocialSecurityNumber;app.NewSSN];
app.Number_of_Withholdings = [app.Number_of_Withholdings;0];
app.YearlySalary = [app.YearlySalary;app.NewYearlySalary];
save('TE566.mlapp',app.EmployeeLastName,app.EmployeeFirstName,app.EmployeeAddressLine1,app.EmployeeAddressLine2,app.EmployeeCity,app.EmployeeState,app.EmployeeZip,app.SocialSecurityNumber,app.Number_of_Withholdings,app.YearlySalary);
app.AddEmployeesButton.Enable = 'on';
end
and its calling function in the main app looked like this:
function AddEmployeesButtonPushed(app, event)
app.AddEmployeesButton.Enable = 'off';
app.NewEmployeeApp = NewEmployee(app,app.NewLastName,app.NewFirstName,app.NewAddressLine1,app.NewAddressLine2,app.NewCity,app.NewState,app.NewZip,app.NewSSN,app.NewYearlySalary);
app.Tab.Title = 'Employees';
app.UITable.Data = table(app.EmployeeLastName,app.EmployeeFirstName,app.EmployeeAddressLine1,app.EmployeeAddressLine2,app.EmployeeCity,app.EmployeeState,app.EmployeeZip,app.SocialSecurityNumber,app.Number_of_Withholdings,app.YearlySalary);
app.UITable.ColumnName = {'Last Name' 'First Name' 'Address Line 1' 'Address Line 2' 'City' 'State' 'Zip Code' 'Social Security #' '# of Withholdings' 'Yearly Salary'};
end
I apologize for the wall of text. I am not terribly great at programming.
Adam Danz
Adam Danz il 11 Lug 2020
I've added to my answer to show a general approach that is similar to yours but simpler. If you have trouble understanding any of the steps, I'd be happy to explain.
I got this to work with the Payroll function no problem - but when I try to do it for a different app, the data I want to get passed as drop down menu items doesn't show up.
code in second app called NewInvoice
% Code that executes after component creation
function startupFcn(app, callerApp, InvoiceDate, InvoiceCustomer, InvoiceQuantity)
app.callerApp = callerApp;
app.DateDatePicker.Value = InvoiceDate;
app.CustomerDropDown.Items = app.callerApp.CustomerCompanyName;
app.CustomerDropDown.Value = InvoiceCustomer;
app.UnitstoInvoiceEditField.Value = InvoiceQuantity;
data I am trying to refence in main app
CustomerCompanyName = {'Village Toy Shop';'Costco';'Wm. K. Walthers, Inc.';'Target';'Whistlestop Hobbies';'Amazon';'F.A.O Schwarz';'Michaels';'HobbyTown USA';'Odds n Ends'};
but I get the following
this is confusing because I passed the data to the dropdown items the same way as I had with the Payroll App
Adam Danz
Adam Danz il 19 Lug 2020
Are you getting any error message? I don't have enough clues here to figure out what's going on. For example, is customer company name an independent variable and in which app? Why does it look like an independant variable in one line but an app property in another line?
Eli Blumen
Eli Blumen il 1 Ago 2020
The customer company name is an independent variable in the main app.
Adam Danz
Adam Danz il 1 Ago 2020
Modificato: Adam Danz il 1 Ago 2020
This line shows that it's a property in your app
app.CustomerDropDown.Items = app.callerApp.CustomerCompanyName;
but this line shows that's an independent variable
CustomerCompanyName = {'Village Toy Shop'; . . . ;'Odds n Ends'};
so there's an inconsistency unless the line above is defined within the properties section.
If that line is not defined within the properties section, you may need to define it this way.
app.callerApp.CustomerCompanyName = {'Village Toy Shop'; . . . ;'Odds n Ends'};
Hi!
I am trying to follow your answer but I am completely lost...
I have two apps: plotMission (main app) and plotMission_segments (dialog app)
When I go to step 3
app.callerApp = callerApp
The following error appears:
Error using plotMission_segments/startupFcn (line 28)
Not enough input arguments.
No sourprise since tha variable callerApp is not defined... What variable should I use here? If I go with :
app.callerApp = plotMission
Then a new window appear...
Adam Danz
Adam Danz il 15 Feb 2021
Based on your error message, it seems like your plotMission app is not passing it's handle to plotMission_segments (step 1).
Here's another answer to this same question that contains demo files to follow.
Thank you for reply.
I have been trying with your examples, but once I close the second app, when I tried to call it in the main app, the handles are lost:
handle to deleted demo_SecondaryApp
Adam Danz
Adam Danz il 16 Feb 2021
> once I close the second app, when I tried to call it in the main app, the handles are lost
That's expected. There's nothing in the documentation nor in my answers that suggests that this works after an app is closed. This doesn't store a copy of an app, it merely grants access to it's handles. If you delete a graphics object, it's handles become useless.
You are totally right. My question is how to send variables from the dialog app to the main one (preferably once I close the dialog app)
What I have tried (without success) is to define a public function in the main app:
methods (Access = public)
function results = updateSegments(app,export_Data)
results = export_Data;
end
end
And in the dialog box, once I click on a push button:
results = updateSegments(app.mission,app.export_Data);
delete(app)
Being mission what you have called CallerApp.
But it is not working... Any ideas?
Adam Danz
Adam Danz il 16 Feb 2021
> My question is how to send variables from the dialog app to the main one (preferably once I close the dialog app)
You can't. Once you close the app, there is no longer access to the app content.
Here are two approaches to consider,
1) Don't close the app, just make toggle its visibility (UIFigure > Visibility property). That way the app and all of its content still exists but is not visible until you turn it back on.
2) Before closing the app, store the data somewhere. You can send app1 to app2, app2 can store all of the needed data, and then app1 can close.
If you have any further questions, please Ask a new question and feel free to tag me.
F S
F S il 3 Set 2021
Hi Adam,
I know the correct way to do this would be to ask a new question, but 2) of your last answer to Jose Maria describes exactely what i want to do! I just don't figure out how to do that. In fact, it is all I want app2 to do, to pass on the data from the spinners to app1, so it inserts them in the function the push button is running.
How do I send the data from app2 to app1, so that they are still there when I close app2?
Thank you, Florian
Adam Danz
Adam Danz il 7 Set 2021
Modificato: Adam Danz il 9 Set 2021
@F S, I've been camping in the woods far from internet. I saw your question on this topic and answered it. 🌳🦝🌲
F S
F S il 10 Set 2021
@Adam Danz great! I hope you had a nice camping trip and enjoyed your time without internet! 🔥
Patrick Mirek
Patrick Mirek il 15 Mar 2022
Hi Adam,
I followed the documentation exactly, but I'm getting an error which says "undefined function '_' for input arguments of type 'double'.", and it occurs when I call the function from the dialog box (in the example given in the documentation, it's the line: updateplot(app.CallingApp,app.EditField.Value,app.DropDown.Value);).
It seems that my secondary app doesn't have access to the public function created in the primary app. Any ideas on how to resolve this?
Adam Danz
Adam Danz il 15 Mar 2022
> It seems that my secondary app doesn't have access to the public function created in the primary app. Any ideas on how to resolve this?
Is updateplot defined in your primary app or the secondary app?
Sharing the entire error message would also be helpful so I can see the function name(s).

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Develop Apps Using App Designer in Centro assistenza e File Exchange

Prodotti

Release

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by