locked
Can't set default properties of programatically created entity RRS feed

  • Question

  • I have followed Michael Washington's article Dynamically Creating Records In The LightSwitch HTML Client and I do this elsewhere in my code without any issue. But this particular instance is acting very strangely and I can't find a cause.

    I set up a change listener on a jQuery checkbox that creates a new Quote Line Item and populates the data. Here is the complete code along with some commented out tries that did not work either.

    function createCheckBox(element, contentItem) {
        var $checkbox = $("<input type='checkbox'/>")
                .css({
                    height: 20,
                    width: 20,
                    margin: "10px"
                })
                .appendTo($(element));
    
        // Determine if the change was initiated by the user.
        var changingValue = false;
    
        $checkbox.change(function () {
            changingValue = true;
            contentItem.value = $checkbox[0].checked;
            changingValue = false;
    
            var newItem = new myapp.QuoteLine;
            ////var newItem = contentItem.screen.QuoteLines.addNew();
            newItem.QuoteNo = contentItem.screen.Quote.QuoteID;
            ////newItem.Quote = contentItem.screen.Quote;
            ////newItem.setQuote(contentItem.screen.getQuote());
            newItem.setQuote(objQuote);
            newItem.ItemNo = 1;
            newItem.ModelNo = contentItem.screen.ModelNo;
            newItem.ProductQty = 1;
            newItem.PMQty = 1;
            newItem.PartNo = "Test";
            newItem.ItemPartNo = "Test";
            newItem.ControlName = "Test";
            newItem.OptionNo = "Test"
            newItem.DisplayName = "Test";
            newItem.EachPrice = 111.11;
            newItem.SellPrice = 0.0;
            newItem.Contact = false;
            newItem.CC = "X";
    
            ////myapp.commitChanges();
            ////myapp.applyChanges();
    
            ////return myapp.activeDataWorkspace.aris_dbData.saveChanges().then(function () {
            ////    contentItem.screen.getQuoteLines();
            ////});
    
            myapp.applyChanges().then(null, function fail(e) {
                msls.showMessageBox(e.message, { title: e.title }).then(function () {
                    myapp.discardChanges();
                    throw e;
                });
            });
        });
        contentItem.dataBind("value", function (newValue) {
            if (!changingValue) {
                $checkbox[0].checked = newValue;
            }
        });
    };

    QuoteNo is a GUID and get set. ModelNo is a string and gets set. I'm assuming that Quote gets set as objQuote seems to have all the proper data in it, though it is difficult to drill down through the intellisense for these objects when in a breakpoint. objQuote is a just a copy of contentItem.screen.Quote.

    Everything else, anything that is just a simple property that is set using =, is undefined once this completes running. I can step though this method and nothing blows up until validation runs. As I said, I can create records dynamically and populate their data just fine elsewhere in the code. So I assume I'm making a fairly obvious mistake due to inexperience. Can anyone spot what I'm doing wrong here?

    Monday, December 14, 2015 10:33 PM

Answers

  • I've solved it. But I'm not really sure what was wrong. I think Visual Studio was just messed up. I originally had the following line:

    newItem.ModelNo = contentItem.screen.ModelNo;

    Digging a bit deeper, I finally noticed the ProductModelNo parameter in the list which is the actual name I have in my database so I changed the code to this to get it to work:

    newItem.ModelNo = contentItem.screen.ModelNo;
    newItem.ProductModelNo = contentItem.screen.ModelNo;

    I then got sidetracked by a colleague and had to install the C++ templates into Visual Studio. This, of course, failed the first time. After the repair and getting back to my project, I noticed that ModelNo was no longer in the Intellisense list. Where it went and why it was there in the first place, I have no idea. But it works just fine without it. Of course now discardChanges is no longer a valid function in myapp so on to track that bug down.

    • Marked as answer by kyle ls Thursday, January 7, 2016 8:20 PM
    Thursday, January 7, 2016 8:20 PM

All replies

  • Hi kyle Is,

    According to your description and the code, I'm confused with your really problem you are facing.

    >>But this particular instance is acting very strangely and I can't find a cause.

    Could you please tell us what is the strangely point that you think? Or you can provide a screenshot to help us understanding your problem.

    In addition, please tell us what the purpose of the code is you pasted. What do you want to implement?

    If possible, please provide a sample project which can let us reproduce your problem. It is benefit to us help you find out what wrong with your code.


    Best Regards,
    Weiwei

    Friday, December 25, 2015 9:25 AM
    Moderator
  • Hi Kyle,

    Can you please try changing this

    var newItem = new myapp.QuoteLine;

    with 

    var newItem = new myapp.QuoteLine();

    Also, i'm not sure where you're defining "objQuote", but in any case, try to make sure that "Quote" is loaded - maybe on the screen's created method ( screen.getQuote(); )

    I hope it helps. 


    • Edited by Nuno Dâmaso Friday, December 25, 2015 8:10 PM code block
    Friday, December 25, 2015 8:06 PM
  • One thing I noticed is that there is no if/then check on the change function, so if the user clicks on the control repeatedly to check/uncheck the control, a new record gets generated on every change, which is probably not what you want.

    When debugging, I find it is often helpful to throw in dummy assignment lines to check for the existence of certain properties.  Try putting in a couple of lines like these:

    var xx = newItem.QuoteNo;

    var zz = 0; // set breakpoint here and hover over 'xx' in the line above to see if it is undefined. If it is, hover over newItem and see if it, too, is undefined.

    Hope this helps,

    R. T. Watkins

    • Proposed as answer by Angie Xu Thursday, January 7, 2016 1:50 AM
    • Marked as answer by Angie Xu Thursday, January 7, 2016 1:50 AM
    • Unmarked as answer by kyle ls Thursday, January 7, 2016 3:27 PM
    • Unproposed as answer by kyle ls Thursday, January 7, 2016 3:28 PM
    Monday, December 28, 2015 2:23 PM
  • I've solved it. But I'm not really sure what was wrong. I think Visual Studio was just messed up. I originally had the following line:

    newItem.ModelNo = contentItem.screen.ModelNo;

    Digging a bit deeper, I finally noticed the ProductModelNo parameter in the list which is the actual name I have in my database so I changed the code to this to get it to work:

    newItem.ModelNo = contentItem.screen.ModelNo;
    newItem.ProductModelNo = contentItem.screen.ModelNo;

    I then got sidetracked by a colleague and had to install the C++ templates into Visual Studio. This, of course, failed the first time. After the repair and getting back to my project, I noticed that ModelNo was no longer in the Intellisense list. Where it went and why it was there in the first place, I have no idea. But it works just fine without it. Of course now discardChanges is no longer a valid function in myapp so on to track that bug down.

    • Marked as answer by kyle ls Thursday, January 7, 2016 8:20 PM
    Thursday, January 7, 2016 8:20 PM
  • The thing to check first is if the data sources on the screen have any related data sources that are being excluded in the Edit Query section under Manage Included Data.  If including those tables still does not solve the issue, then  I've found that many times when items are coming back as "undefined" even after doing things like wrapping their check code inside promise-dependent functions (like .then() or .done()), the simplest way to get the code to work is to wrap the check inside a setTimeout() block, as those are executed only after all .render() and .postRender() methods have completed, and jQuery Mobile has done its final manipulation of the DOM.

    Thursday, January 7, 2016 9:36 PM