I guess more generally, I'm not sure when using this tag is supposed to be used:

<script language="Cache" runat="server">

It's clearer when to use:

<script language="cache" method="OnPreHTTP">>

<script language="Cache" method="SomeMethod">

If I move my code from the tag with the runat="Server" argument, then I can't seem to access the %request.Data object.  If I keep my code in that block, I can't use any &js<> syntax.

Can someone explain in a kindergarten way to me where this lives in the HTTP lifecycle?

@Warlin Garcia thank you!  In fact, I'm doing something like this but I must be missing something.

Form has an attribute:

onSubmit="return #server(..Validate(date1,date2))#"

Validate() is in the CSP code as such:

<script language="Cache" method="Validate" arguments="startDate:%Date,endDate:%Date">
   startDate=$ZDH(startDate,3)
   endDate=$ZDH(endDate,3)
   if startDate>endDate {
  &js<
         alert('Invalid date range.');
          return false;>
   }
 </script>

I get my alert, but my page continues to reload, which would be fine I guess, but the %request.Data object with the data from the form is still populated. 

So when the following block runs, the process that I don't want to execute on the server side keeps going when I want it to not run.  I guess I'm not sure what returning false to the onSubmit actually does?  What is does not seem to do is clear or not set the %request.Data form nodes.  

 <script language="Cache" runat="server">
 
  If ($Data(%request.Data("FormThatWasSubmitted",1))) {
         startdate=%request.Data("STARTDATE",1)
         startdate=$ZDH(startdate,3)
  
        enddate=%request.Data("ENDDATE",1)
        enddate=$ZDH(enddate,3)

        job process^routine(startdate, enddate)

</script>

Side note: I'm jobbing off that routine which sends and email . . . if I do the job in the foreground with a DO the email sense, if I use JOB the email does not send (file still generates).  Anyone know why?

@Timothy Leavitt thank you!

I wouldn't have thought to do form logic OnPreHttp . . . the documentation suggests checking the %request.Data node for the form in the runat="server" script.  This does make sense if you plan to do a redirect, I think.

Thank you for helping me better understand the runat="server" timing.  It's been a while since I've touched PHP but this all rings a bell.  

Ah ok, so just onClick=return fromAJavaScriptFunction()?

Define that in <script language="javascript">, right?

Returning 0 on the server-side method didn't seem to stop the form, my file was still generated from the process that runs after checking the %reqeust.Data("sumbitButton",1) node.  But I think I'll get rid of this anyway.

<script language="Cache" method="Validate" arguments="startDate:%Date,endDate:%Date">
   
   startDate=$ZDH(startDate,3)
   endDate=$ZDH(endDate,3)
   if startDate>endDate {
  &js<
  alert('Invalid date range.');>
  quit 0
   }
   quit 1
 </script>

I turned on that auditing btw and I'm not seeing anything. But doing some other debugging it seems that the %Net.SMTP.Send() method is getting hung up.  If I step through it, it's endless lines of code.  I put a break after the Send() method and it never reaches it.  Not sure if it's infinite looping or just getting hung.

Michael Davidovich · Apr 11, 2022 go to post

I have implemented @Dmitry Maslennikov's solution below, but I wonder @Nigel Salm if you'd had success with any of those extensions to specify pages to open in browsers.  If you search the extension library for "open in browser" many, many options come up but they all seem to focus on HTML pages.
 

Michael Davidovich · Apr 11, 2022 go to post

For other n00bs like me . . . in GitHub you click the Releases link on the code page and you can find the packaged code.

Michael Davidovich · Apr 22, 2022 go to post

@Guilherme Mendes Thank you.  That's exactly it.  That documentation was misleading, and I think it's fair to say so since there are so many ways to embed this and that into that and this!  

Michael Davidovich · May 13, 2022 go to post

A update already: it seems the CSS has now updated on both browsers, but the HTML is still not updated.  This lag seems quite off.  When I update CSS locally (not Docker) it changes on refresh.  

Michael Davidovich · May 13, 2022 go to post

After 30 mins or so both the CSS change (changed from Ariel to Times) and the HTML (added "TESTING!!!" in the heading) ended up refreshing.

Why is there this lag?  Must be the browser?

Michael Davidovich · May 13, 2022 go to post

Using the demo, the web folders are in the container.  I will try this though and see if it changes things.

Michael Davidovich · May 13, 2022 go to post

@Dmitry Maslennikov This seemed to help as the changes to the HTML are instant with the changed setting, however the CSS didn't change.  After clearing the browser cache then I saw the changes.  Assuming there must be a browser setting that hold on to the CSS.  I'm not sure.  

We haven't quite solved this for our own app.  All the progress thusfar has been in the demo app from GitHub (the coffee shop).

Michael Davidovich · May 19, 2022 go to post

Thanks @Pravin Barton! This is helpful just to get a better send of how others use the framework.  We are still baby stepping into all of this and don't want to rush into implementing it as it's harder to untangle and "redo" once we're really rolling.  

Related to keeping your unit tests separate: so you don't export your unit test class files to a different ^UnitTestRoot?  Rather the ^UnitTestRoot is where the unit tests live in the cloned repository? 

@Timothy Leavitt thanks for the link to that post. I'm sure I've seen it before but more will make sense now that I have more experience with this.  

Related to the test coverage tool: do you have best practices or shortcuts as an individual developer?  Do you run the Test Coverage tool as your developing to see what lines of code are covered or not? We are thinking through how to arm the developer to write the most complete unit tests before sending to the remote and having Jenkins automatically rebuild everything and do the more extensive reporting.

Really appreciate the responses! 

@Eduard Lebedyuk Thank you.  This IS true since I'm debugging a method defined on CSP page, I'm writing things to a global to check them on the terminal.  So that explains that.

How do you know that means that?

For some more context, I stopped trying to see what was going on by setting globals to debug.  I set the %response.TraceDump=1 so I can see the %session variable which is were I'm storing the value to the key of the object:

%session.Data("key")=array.%Get("key")

This is still no working as expected.  I even stepped through the code in the command line by calling the zLabel in the INT routine generated from the CSP and it worked as expected there.  

Michael Davidovich · Jul 26, 2022 go to post

Resolved by removed a lock on some global called ^oddProcess("default_project") or something like that.

Michael Davidovich · Jul 26, 2022 go to post

Opening this back up because getting the classes to my local repo is proving to be challenging.

In VS Code I was able to open the code on the server, click 'Download' on the package and download it to my local repo.  Problem is that the only two classes that show up are impl and spec, but not disp.

In a similar vein, if I used the API to update the spec the updated code was now on the server (just as it first got there when I did the create using the API).  Now when I try to download the updated package to my local, well, it won't let me.  I have to download each file which isn't too cumbersome, but it's just one.  

How can I:

1) Get the disp class to get to my local so I can ship it to the remote repo and other servers

2) Make the update process using the API smoother

3) Bonus: create a web app programmatically so when my colleague starts to use it for his front end dev, he's ready to go.

Michael Davidovich · Jul 27, 2022 go to post

@Brett Saviano 

Thanks for your reply!  I am familiar with that doc but didn't reference it because we already set up for client side development.  Yes I could just edit the spec and impl classes on the server, but since our source control isn't hooked into the server, so I would still have the issue of getting the code generated and updated on the server (from /api/mgmt/) to my local repo.  

I tried the ObjScript Explorer to export, but it seems I can only export ALL the files.  That's not practical when I just want to export one package.  

However, using the Export Code From Server command does let me select individual classes so that's great! 

Question: if we scale up with use of OpenAPI 2.0, the use of /api/mgmt/ and stick with client side dev, how can we make source control more smooth?  In other words, is there a way to automatically export impl and spec classes to the client whenever they are updated?

Good to know about the disp class and makes sense.  One less thing to worry about.  

While I was playing around with this, a few times after compiling changes to the impl class, the disp class was then removed from the server (this was in Studio before I figured out to get them on the client).  Have you experienced this before and know what might cause that to happen?

Michael Davidovich · Jul 27, 2022 go to post

Thank you, Brett.  I must still be missing something.

In the ObjectScript explorer, if I right click on the project I have an option to 'Export Project Contents'.  If I right click on any package or file, I only have three options: Remove from Project, Server Source Control and Server Command Menu.

I've skimmed the doc again but don't see anything obvious in terms of settings that I might be missing. 

Any ideas?

Michael Davidovich · Jul 27, 2022 go to post

Thanks and agreed. It was on my locally installed IRIS on my own machine so I wasn't too worried, but yes, would never do that on a live server that others use or have access to.

Michael Davidovich · Jul 27, 2022 go to post

@Brett Saviano 

Sorry, back again. Feeling like a dunce here . . . I updated my API using my OpenApi 2.0 JSON spec and the /api/mgmt POST call and looking in Studio, I can see my spec.cls is showing v 1.5 as I expect. When I refresh the explorer view (which is the live server, yes?) I'm still on v 1.4 which is my old spec.

Is there some other setting that might be preventing this refresh?

I looked here: Settings Reference - InterSystems ObjectScript for VS Code (intersystems-community.github.io), but I didn't find anything that stood out as a setting that would stop a refresh of the explorer view from showing updated classes on the server.

Michael Davidovich · Jul 27, 2022 go to post

@Eduard Lebedyuk 

Thanks for this article.  I have followed this along with the online documentation and I am having an issue that maybe you can offer guidance on?

I have my web app setup, enabled, set to no authentication (just testing and learning right now so trying to make it as simple as possible), and my generated "Package.disp" class in the dispatch parameter.  

It WAS working.  Then I tried to call it from a React app using Axio to make the call and there were some CORS issues.  So I started playing with those settings 1) added "Access-Control-Allow-Origin=*" to the header of the request 2) added "Parameter HandleCorsRequest = 1;" to the Package.spec and 3) now that I've seen it in your article, added "x-ISC_CORS": true, to the path setting in the spec.

401 error every time. 

I even changed the auth in Postman from no auth to basic auth and put in my localhost creds.  401.  I've looked at the Auit Log and I see some activity every time I make the call but I'm not sure how to interpret. Even when I try to revert to my setup pre-playing-around-with-CORS, I get the 401 again.

What could be causing a 401 when everything is setup to be so relaxed?

Michael Davidovich · Jul 27, 2022 go to post

For those watching at home: ensure you grant your application a role in the settings.  I didn't do this before and it worked, so not sure what happened that it got removed or all of a sudden needed the setting, but this is a key check.

Michael Davidovich · Jul 29, 2022 go to post

@David Hockenbroch 

Thanks!

I think the major assumption I forgot to mentioned was that this is an existing web app built on CSP that we would like to modernized with REST APIs.  

So to begin with the methods are defined in the CSP file and now we want to port them over to a REST API.  Since it's a generated class I get nervous calling it like I am but I don't see another way.

Michael Davidovich · Aug 12, 2022 go to post

@Timothy Leavitt 

Another question popping up.  How do I access the test result on the command line to see if it failed?  When I run DebugRunTestCase, the the URL spits out with the result index in it.  I created an instance of Manager and then ran the method but I don't seem to get any properties or output that say "this failed."

Thoughts here?

Michael Davidovich · Aug 12, 2022 go to post

Ok thanks, I'll take a look.

This begs the question: if it's not straightforward, is this a typical implementation?  The CircleCI examples give all these test examples that are run from the command line (e.g. python test, npm test), but of course the IRIS setup is a little different.

Michael Davidovich · Aug 16, 2022 go to post

@Benjamin De Boe 
 

I went nuts today working with some of this stuff.  Can I confirm a few points:

- $SYSTEM.SQL.Schema.QueryToTable() does not exist in my IRIS version however $SYSTEM.SQL.QueryToTable() does.  I have IRIS 2021. Are these different things?

- I ended up using a CREATE OR REPLACE VIEW because doing a CREATE TABLE ... AS SELECT would create a table but return no data (I would even do a DROP TABLE operation first to make sure all was clear.  Am I correct in saying that a create table as select is strictly as COPY operation of an existing table.  Since I was effectively creating a new table with new headers, the view worked better here.  Is that the difference?

- To clarify, I used the $SYSTEM command to create table from query, because I kept getting errors with create table as select (didn't like my AS statement).  What could have gone wrong there?