FrankTheTank
FrankTheTank

Reputation: 785

getElementById().value Returns Undefined

I am trying to store references to a multitude of inputs on my page in javascript variables to be passed to a webmethod on my backend. Because my page only pulls up and fills one of two hidden forms with data when the page loads some of the values of the inputs are 'undefined'. This throws an error that results in my webmethod to update a database never being called.

An example of one of my javascript call is as follows:

const fields = {
                    name: '<%=eventFormName.ClientID%>',
                    type: '<%=eventFormType.ClientID%>',
                    subjectLineSD: '<%=eventFormSubjectLineSD.ClientID%>',
                    summarySD: '<%=eventFormSummarySD.ClientID%>',
                    resourcesAffectedSD: '<%=eventFormResourcesAffectedSD.ClientID%>',
                    peopleAffectedSD: '<%=eventFormPeopleAffectedSD.ClientID%>',
                    workAroundSD: '<%=eventFormWorkAroundSD.ClientID%>',
                    startTimeSD: '<%=eventFormStartTimeSD.ClientID%>',
                    endTimeSD: '<%=eventFormEstimatedTimeOfResolutionSD.ClientID%>',
                    subjectLinePO: '<%=eventFormSubjectLinePO.ClientID%>',
                    summaryPO: '<%=eventFormSummaryPO.ClientID%>',
                    resourcesAffectedPO: '<%=eventFormResourcesBeingChangedPO.ClientID%>',
                    changeBenefitsPO: '<%=eventFormChangeBenefitsPO.ClientID%>',
                    impactOnEndUsersPO: '<%=eventFormImpactOnEndUsersPO.ClientID%>',
                    startTimePO: '<%=eventFormProposedStartDatePO.ClientID%>',
                    endTimePO: '<%=eventFormProposedEndDatePO.ClientID%>',
                }

                const values = Object.keys(fields).map((key) => {
                    const elm = document.getElementById(fields[key])
                    if (elm) {
                        return elm.value;
                    }
                    return null;
                })

                PageMethods.updateData.apply(this, values);

In other words, how could I allow for some of these variables to have value 'undefined' or 'null' to then be passed through my PageMethods call to my backend?

Also, here is my webmethod on the backend for reference:

[WebMethod]
    public static string updateData(string[] values)
    {
        try
        {
            SqlCommand command;
            SqlConnection sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString);
            command = new SqlCommand("updateNetEvent", sqlConn);

            if (values[1] == "Planned Outage")
            {
                // NetEvent Parameters
                command.Parameters.AddWithValue("@Name", values[0]);
                command.Parameters.AddWithValue("@Type", values[1]);
                command.Parameters.AddWithValue("@SubjectLine", values[9]);
                command.Parameters.AddWithValue("@StartTime", values[14]);
                command.Parameters.AddWithValue("@EndTime", values[15]);

                // UserAction Parameters
                command.Parameters.AddWithValue("@Summary", values[10]);
                command.Parameters.AddWithValue("@ResourcesAffected", values[11]);
                command.Parameters.AddWithValue("@ChangeBenefits", values[12]);
                command.Parameters.AddWithValue("@PeopleAffected", System.Data.SqlTypes.SqlString.Null);
                command.Parameters.AddWithValue("@ImpactOnEndUsers", values[13]);
                command.Parameters.AddWithValue("@WorkAround", System.Data.SqlTypes.SqlString.Null);
                command.Parameters.AddWithValue("@Status", "A");
                command.Parameters.AddWithValue("@PerformedBy", "placeholder"); // TODO: Update
                command.Parameters.AddWithValue("@PerformedOn", DateTime.Now.ToString());
            }
            else if (values[1] == "Service Disruption")
            {
                // NetEvent Parameters
                command.Parameters.AddWithValue("@Name", values[0]);
                command.Parameters.AddWithValue("@Type", values[1]);
                command.Parameters.AddWithValue("@SubjectLine", values[2]);
                command.Parameters.AddWithValue("@StartTime", values[7]);
                command.Parameters.AddWithValue("@EndTime", values[8]);

                // UserAction Parameters
                command.Parameters.AddWithValue("@Summary", values[3]);
                command.Parameters.AddWithValue("@ResourcesAffected", values[4]);
                command.Parameters.AddWithValue("@ChangeBenefits", System.Data.SqlTypes.SqlString.Null);
                command.Parameters.AddWithValue("@PeopleAffected", values[5]);
                command.Parameters.AddWithValue("@ImpactOnEndUsers", System.Data.SqlTypes.SqlString.Null);
                command.Parameters.AddWithValue("@WorkAround", values[6]);
                command.Parameters.AddWithValue("@Status", "A");
                command.Parameters.AddWithValue("@PerformedBy", "placeholder"); // TODO: Update
                command.Parameters.AddWithValue("@PerformedOn", DateTime.Now.ToString());
            }

            command.CommandType = System.Data.CommandType.StoredProcedure;
            sqlConn.Open();
            command.ExecuteNonQuery();
            sqlConn.Close();
            return "./StartPage.aspx";
        }
        catch (Exception ex)
        {
            Console.WriteLine("ERROR: " + ex.ToString());     // Add a log helper to display errors here
            return "Error in updateData WebMethod";
        }

    }

Upvotes: 0

Views: 2335

Answers (2)

dzm
dzm

Reputation: 23534

You're trying to get elements that do not exist, this is why you get thrown. You need to check this, before you call .value.

var name = null
var nameElement = document.getElementById('<%=eventFormName.ClientID%>');
if (nameElement) {
  name = nameElement.value
}

EDIT:

Because it's bothering me a bit that your code is gonna be messy. You could do something like this below to make things a bit more dynamic. Replace the values for each of the properties with your asp tags and update how you call your PageMethods.updateData to PageMethods.updateData.apply(this, values)

const fields = {
  name: 'name',
  type: 'type',
  subjectLineSD: '<%=eventFormSubjectLineSD.ClientID%>',
  summarySD: '',
  resourcesAffectedSD: '',
  peopleAffectedSD: '',
  workAroundSD: '',
  startTimeSD: '',
  endTimeSD: '',
  subjectLinePO: '',
  summaryPO: '',
  resourcesAffectedPO: '',
  changeBenefitsPO: '',
  impactOnEndUsersPO: '',
  starTimePO: '',
  endTimePO: '',
  endTimePO: ''
}

const updateData = function(name, type) {
  console.log(name)
  console.log(type)
}

const values = Object.keys(fields).map((key) => {
  const elm = document.getElementById(fields[key])
  if (elm) {
    return elm.value
  }
  return null
})

updateData.apply(this, values)
<input id="name" value="NAME">
<input id="type" value="TYPE">

Upvotes: 3

foxinatardis
foxinatardis

Reputation: 156

Your error results from trying to get the value of an element not on the page.

If you call var name = document.getElementById('foo') but there is no element with id='foo' then the variable 'name' is null. Hence the error Cannot read property 'value' of null

If you set your variables first checking that the element exists, this should solve your problem e.g.

var name = document.getElementById('foo') ? document.getElementById('foo').value : null;

Upvotes: 0

Related Questions