Base solution for your next web application
Open Closed

Timing problem insert update data in three db tables and show newly added/edited in datatable #8652


User avatar
0
geoteam created

Hello, I have three database tables Address, PersonCompany and a link table AddressPersonCompany (m:n). In the frontend there is a display form which is very similar to the page "users" - a text field for a search word and a datatable to display the search result (addresses).

Following the instructions "Using-Stored-Procedures,-User-Defined-Functions-and-Views" I created three custom repositories.

If a new address is created via the modal window, first the Address table, then the PersonCompany table and finally the link table AddressPersonCompany is filled. In AddressPersonCompany there is an additional column in which a search text is written. For test purposes, the search text is predefined as "Spieth".

The problem is that before the insert the search was restricted to "S", for example. Accordingly the new dataset should appear immediately in the datatable, because it also starts with "S". After the insert, as with "Users" a

function getAddresses() {
            dataTable.ajax.reload();
        }

triggered. However, the new data record is only displayed after a page update (for example, F5).

When the record is updated, you can see that the Address and PersonCompany table is written on time, but the search text is changed too late. In the Datatable the changed values already exist, but the dataset should not be displayed anymore, because the search text was changed from "Spieth" to e.g. "Test".

Therefore I think that the function "getAddresses()" is executed before the dataset has been updated or completely inserted.

Can you give me a hint how to solve the problem?

Here is my insert function

public async Task CreateOrUpdateAddress(CreateOrUpdateAddressInput input)
        {
            if (input.AddressPersonCompanyId.HasValue)
            {
                // Update addressPersonCompany
                await UpdateAddressAsync(input);
            }
            else
            {
                // Insert addressPersonCompany
                await InsertAddressAsync(input);
            }            
            
            // Save changes to database
            //await CurrentUnitOfWork.SaveChangesAsync();            
        }
        
protected virtual async Task InsertAddressAsync(CreateOrUpdateAddressInput input)
        {
            var addressPersonCompany = ObjectMapper.Map<AdrAddressPersonCompany>(input);

            addressPersonCompany.AddressId = await _addressRepository.InsertAndGetIdAsync(addressPersonCompany.Address);
            addressPersonCompany.PersonCompanyId = await _personCompanyRepository.InsertAndGetIdAsync(addressPersonCompany.PersonCompany);
            addressPersonCompany.Searchtext = "Spieth";
            
            await CurrentUnitOfWork.SaveChangesAsync(); //To get new user's Id.

            //AdrAddressPersonCompany _newAdrAddressPersonCompany = await _addressPersonCompanyRepository.InsertAsync(addressPersonCompany);
            var addressPersonCompanyId = await _addressPersonCompanyRepository.InsertAndGetIdAsync(addressPersonCompany);

            await CurrentUnitOfWork.SaveChangesAsync(); //To get new user's Id.
            // Create searchtext in table adrAddressPersonCompanies
            //await _addressPersonCompanyRepository.UpdateSearchtextOnAddressPersonCompanies(addressPersonCompany.AddressId, addressPersonCompany.PersonCompanyId, _session.TenantId);
            }
            
protected virtual async Task UpdateAddressAsync(CreateOrUpdateAddressInput input)
        {
            //Update existing AddressPersonCompany
            var address = await _addressRepository.GetAsync(input.AddressId);
            address.Street = input.AddressStreet;
            address.Location = input.AddressLocation;
            address.HouseNumber = input.AddressHouseNumber;
            address.Zipcode = input.AddressZipcode;
            await _addressRepository.UpdateAsync(address);


            var personCompany = await _personCompanyRepository.GetAsync(input.PersonCompanyId);
            personCompany.NameCompany = input.PersonCompanyNameCompany;
            personCompany.Firstname = input.PersonCompanyFirstname;
            personCompany.TitleId = input.PersonCompanyTitleId;
            personCompany.CompanyAddOn = input.PersonCompanyCompanyAddOn;
            await _personCompanyRepository.UpdateAsync(personCompany);

            await CurrentUnitOfWork.SaveChangesAsync(); //To get new user's Id.

            // Create searchtext in table adrAddressPersonCompanies
            await _addressPersonCompanyRepository.UpdateSearchtextOnAddressPersonCompanies(input.AddressId, input.PersonCompanyId, _session.TenantId);
        }

and the standard part of _CreateOrEditModal

this.save = function () {
            if (!_$form.valid()) {
                return;
            }

            var address = _$form.serializeFormToObject();

            _modalManager.setBusy(true);

            // direkt die Funktion aus AddressAppService verwendet
            _addressService.createOrUpdateAddress(address).done(function () {
                abp.notify.info(app.localize('SavedSuccessfully'));
                _modalManager.close();
                abp.event.trigger('app.createOrEditAddressModalSaved');
                //location.reload();
            }).always(function () {
                _modalManager.setBusy(false);
            });
        };

4 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Do you change search text on the list page using code ?

    done function of _addressService.createOrUpdateAddress will be called when the server side response is received. So, data is definitely inserted into the database.

    By the way, you can place a debugger; in your client side code and check database tables to see if the records are inserted or not.

  • User Avatar
    0
    geoteam created

    Hi ismcagdas, thanks for reply. Searchtext is used for test purposes and the value "Spieth" is written "hard" into database. It's read from modal form text field and is not changed. In real application searchtext should be written by a stored procedure. The only special thing about the Searchtext column in the database is that it is a full text indexed column.

    var dataTable = _$addressSearchTable.DataTable({
                paging: true,
                serverSide: true,
                processing: true,
                listAction: {
                    ajaxFunction: _addressService.getAddressPersonCompaniesForDatatable,
                    inputFilter: function () {
                        return {
                            filter: $('#FilterAddressText').val()//,
                            //permissions: _selectedPermissionNames,
                            //role: $("#RoleSelectionCombo").val(),
                            //onlyLockedUsers: $("#UsersTable_OnlyLockedUsers").is(':checked')
                        };
                    }
                },
    

    Because of a test with a breakpoint I'm writting about a time problem. When I place a breakpoint at the end of "CreateOrUpdateAddress" nothing is written in database. After one step more (F10) out of the function debugger stops at function "public class AppnameEntityFrameworkCoreModule : AbpModule" at line "Configuration.Modules.AbpEfCore().AddDbContext<AppnameDbContext>(options =>" and data is written in database. After that done-function and dataTable.ajax.reload() is called. In this case the new address is displayed in the datatable as expected.

    But when I run the insert dialog without breakpoint, the new address isn't shown in the datatable. Only after a refresh.

    Similar behavior with update dialog. I can see because of the updated data in the datatable, that address and name data is written in database, but the updated searchtext is written to late, so that for example changed name from "Spieth" to "Test", search still finds the row with searchtext "Spieth" and not the updated row with "Test".

  • User Avatar
    0
    geoteam created

    Hi ismcagdas, I think my problem was the fulltextsearch in database. The magic words are "changes might not be reflected immediately in the full-text index.". So database was updated but when "dataTable.ajax.reload();" was executed the fulltextindex was not refreshed. Thanks for your time.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Thank you for your feedback :)