<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Rachel Soderberg</title>
    <description>The latest articles on Forem by Rachel Soderberg (@rachelsoderberg).</description>
    <link>https://forem.com/rachelsoderberg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F122514%2F341b55b2-361b-4842-956d-b6138a33a300.jpeg</url>
      <title>Forem: Rachel Soderberg</title>
      <link>https://forem.com/rachelsoderberg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rachelsoderberg"/>
    <language>en</language>
    <item>
      <title>Creating a Record Using C# .NET and the Salesforce REST API</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Tue, 25 Aug 2020 17:28:08 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/creating-a-record-using-c-net-and-the-salesforce-rest-api-4n9b</link>
      <guid>https://forem.com/rachelsoderberg/creating-a-record-using-c-net-and-the-salesforce-rest-api-4n9b</guid>
      <description>&lt;p&gt;This article is a continuation of the Salesforce REST API Services series. In this article we are operating under the assumption that you have already set up your Salesforce org and built an application that successfully authenticates with Salesforce and logs in. The steps in this tutorial will not work without the resulting AuthToken from your Salesforce org.&lt;/p&gt;

&lt;p&gt;In this tutorial we'll be creating a new Account record in our Salesforce org using our C# .NET application. Creating a record in an external application is incredibly useful for automated processing of data such as customer orders or shipments, allowing the application to perform the work of adding records that do not already exist.&lt;/p&gt;

&lt;h1&gt;Creating A Record&lt;/h1&gt;

&lt;p&gt;As with the other examples, we will encourage re-usability in our code with a CreateRecord() method and use our API Endpoint, Service URL, and AuthToken for our connection to the Salesforce org.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  private string CreateRecord(HttpClient client, string createMessage, string recordType)
  {
        HttpContent contentCreate = new StringContent(createMessage, Encoding.UTF8, "application/xml");
        string uri = $"{ServiceUrl}{ApiEndpoint}sobjects/{recordType}";

        HttpRequestMessage requestCreate = new HttpRequestMessage(HttpMethod.Post, uri);
        requestCreate.Headers.Add("Authorization", "Bearer " + AuthToken);
        requestCreate.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
        requestCreate.Content = contentCreate;

        HttpResponseMessage response = client.SendAsync(requestCreate).Result;
        return response.Content.ReadAsStringAsync().Result;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now that we have the framework to send a Create request to Salesforce, we can build a method to create an Account with the different pieces of customer data we need to populate. These fields and values will vary greatly depending on your needs, but I've given you a couple of fields that will typically be used. These values won't be hard coded as seen in the below example, they would typically be passed from your database, an order payload, or other method of customer data being passed to the application for processing. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  private string CreateAccount(HttpClient client, Order order)
  {
        string companyName = "Bob's Builders";
        string phone = "123-456-7890";

        string createMessage = $"&amp;lt;root&amp;gt;" +
            $"&amp;lt;Name&amp;gt;{companyName}&amp;lt;/Name&amp;gt;" +
            $"&amp;lt;Phone&amp;gt;{phone}&amp;lt;/Phone&amp;gt;" +
            $"&amp;lt;/root&amp;gt;";

        string result = CreateRecord(client, createMessage, "Account");

        XDocument doc = XDocument.Parse(result);
        string id = xmlHelper.RemoveTags(doc.Root.FirstNode.ToString());
        string success = xmlHelper.RemoveTags(doc.Root.LastNode.ToString());

        if (success != "true")
        {
            logger.SalesforceError("Create", "Account");
            return null;
        }

        logger.SalesforceSuccess("Create", "Account", id);
        return id;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You may have noticed that the code in this tutorial looked very similar to updating and querying records in the previous tutorials. This leads me to a potential later project where I may look into building a single "SalesforceConnection" method that can perform all of these functions without all the very similar code.&lt;/p&gt;

&lt;p&gt;For now though, this marks the end of this tutorial series. Let me know what other Salesforce topics you'd like to read or learn about!&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;If you'd like to catch up with me on social media, come find me over on &lt;a href="https://twitter.com/RachSoderberg"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/rachelsoderberg/"&gt;LinkedIn&lt;/a&gt; and say hello!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>salesforce</category>
      <category>rest</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Updating a Record Using C# .NET and the Salesforce REST API</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Tue, 14 Jul 2020 21:01:38 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/updating-an-account-using-c-net-and-the-salesforce-rest-api-2d0c</link>
      <guid>https://forem.com/rachelsoderberg/updating-an-account-using-c-net-and-the-salesforce-rest-api-2d0c</guid>
      <description>&lt;p&gt;This article is a continuation of the Salesforce REST API Services series. In this article we are operating under the assumption that you have already set up your Salesforce org and built an application that successfully authenticates with Salesforce and logs in. The steps in this tutorial will not work without the resulting AuthToken from your Salesforce org. Ideally, your application also retrieves an AccountId, but this can be passed as a string as well.&lt;/p&gt;

&lt;p&gt;In today's tutorial we're going to perform an update to an Account record in our Salesforce org. Updating a record from a C# application is useful in cases where records must be updated automatically on an object-by-object basis, such as modifying orders, updating customer records, or setting a custom status after completing a task. Your application can submit an update with all of the info from your use case and in moments your Salesforce record will reflect the new values.&lt;/p&gt;

&lt;h1&gt;Performing an Update&lt;/h1&gt;

&lt;p&gt;As suggested in part 2 of this series, I suggest creating a generic UpdateRecord() method as this code can potentially be reused dozens of times in a code base. This is going to look very similar to the QueryRecord() method we created in the last step, but there are some differences such as the use of HttpContent used to represent our HTTP entity body and content headers, where we'll pass in our encoded XML message.&lt;/p&gt;

&lt;p&gt;Also similarly to a query, we are using our API Endpoint, Service URL, and AuthToken to make and confirm a successful connection with our Salesforce org.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    private string UpdateRecord(HttpClient client, string updateMessage, string recordType, string recordId)
    {
        HttpContent contentUpdate = new StringContent(updateMessage, Encoding.UTF8, "application/xml");

        string uri = $"{ServiceUrl}{ApiEndpoint}sobjects/{recordType}/{recordId}?_HttpMethod=PATCH";

        HttpRequestMessage requestUpdate = new HttpRequestMessage(HttpMethod.Post, uri);
        requestUpdate.Headers.Add("Authorization", "Bearer " + AuthToken);
        requestUpdate.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
        requestUpdate.Content = contentUpdate;

        HttpResponseMessage response = client.SendAsync(requestUpdate).Result;
        return response.Content.ReadAsStringAsync().Result;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now let's say we're writing a service that updates a customer's phone and mobile numbers on their Account record.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public string UpdateCustomerAccountPhoneNumbers()
    {
        string phone = "123-123-1234";
        string mobile = "456-456-4567";

        string updateMessage = $"&amp;lt;root&amp;gt;" +
            $"&amp;lt;Phone&amp;gt;{phone}&amp;lt;/Phone&amp;gt;" +
            $"&amp;lt;Phone2__c&amp;gt;{mobile}&amp;lt;/Phone2__c&amp;gt;" +
            $"&amp;lt;/root&amp;gt;";

        string result = UpdateRecord(Client, updateMessage, "Account", accountId);

        if (result != "")
        {
            logger.SalesforceError("Update", "Account");
            return null;
        }

        logger.SalesforceSuccess("Update", "Account", accountId);
        return accountId;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I've included the error handling in this example as well because one way you can confirm you've actually updated the record successfully is when you're returned an empty result string in debug mode. If anything went wrong, such as an invalid field name being used, you will get back an error message to help you resolve the issue. Let's say I tried to do 123-456-7890 in the above example. The update would fail and I would receive this response:&lt;/p&gt;

&lt;p&gt;"&amp;lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&amp;gt;INVALID_FIELDNo such column 'PhoneNumber' on entity 'Account'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names."&lt;/p&gt;

&lt;p&gt;With an update result of "" you can be certain your record was updated correctly and you can continue on with further functionality.&lt;/p&gt;

&lt;p&gt;Next in this series we will cover the creation of a new Account record, which is helpful when our query method results in no records found.&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;If you'd like to catch up with me on social media, come find me over on &lt;a href="https://twitter.com/RachSoderberg"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/rachelsoderberg/"&gt;LinkedIn&lt;/a&gt; and say hello!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>salesforce</category>
      <category>rest</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Querying a Record Using C# .NET and the Salesforce REST API</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Thu, 11 Jun 2020 19:06:00 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/querying-an-account-using-c-net-and-the-salesforce-rest-api-4o5k</link>
      <guid>https://forem.com/rachelsoderberg/querying-an-account-using-c-net-and-the-salesforce-rest-api-4o5k</guid>
      <description>&lt;p&gt;This article is a continuation of the Salesforce REST API Services series. In this article we are operating under the assumption that you have already set up your Salesforce org and built an application that successfully authenticates with Salesforce and logs in. The steps in this tutorial will not work without the resulting AuthToken from your Salesforce org.&lt;/p&gt;

&lt;p&gt;In today's tutorial we're going to perform a Query to our Salesforce org to return some information from an existing Account. This gives you the freedom to determine whether a specific Account exists so you can then programmatically perform actions on the Account from your .NET application instead of within Salesforce itself.&lt;/p&gt;

&lt;h1&gt;Performing a Query&lt;/h1&gt;

&lt;p&gt;I don't typically use these tutorials to cover specifics in programming style, but in this case I would like to briefly suggest creating a generic method specifically for performing queries. This set of code has the potential to be used numerous times within a single application, or even within a single function, and should not be rewritten each and every time. My code examples today will reflect this focus on smaller, more focused, software architecture.&lt;/p&gt;

&lt;p&gt;The first step is to create a QueryRecord() method and pass in our HttpClient object and a queryMessage string. This message is identical to a SOQL query you would to perform this query in the Salesforce Developer Console. (This is exactly the same as the query string used for the SOAP API as well)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    private string QueryRecord(HttpClient client, string queryMessage)
    {
        string restQuery = $"{ServiceUrl}{ApiEndpoint}query?q={queryMessage}";

        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, restQuery);
        request.Headers.Add("Authorization", "Bearer " + AuthToken);
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        HttpResponseMessage response = client.SendAsync(request).Result;
        return response.Content.ReadAsStringAsync().Result;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;What I found most interesting about the RESTful service is that we are sending an HTTP Request to Salesforce for our query string using the known API Endpoint and the Service URL passed back from the authentication results instead of using a created binding object as seen in the SOAP API.&lt;/p&gt;

&lt;p&gt;Next we add some information to the header, including the name of the header and its value from the AuthToken returned by our authentication. A response is sent back, which we can return the result of to our requesting method as a string.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public void GetAccount()
    {
        string companyName = "My Company";
        string queryMessage = $"SELECT Id, Name, Phone, Type FROM Account WHERE Name = '{companyName}'";

        JObject obj = JObject.Parse(QueryRecord(Client, queryMessage));

        if ((string)obj["totalSize"] == "1")
        {
            // Only one record, use it
            string accountId = (string)obj["records"][0]["Id"];
            string accountPhone = (string)obj["records"][0]["Phone"];
        }
        if ((string)obj["totalSize"] == "0")
        {
            // No record, create an Account
        }
        else
        {
            // Multiple records, either filter further to determine correct Account or choose the first result
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you debug the program and expand the results when the queryMessage is parsed as a JObject, you'll see a fairly substantial JSON payload. At this point the most important piece is the value in the "totalSize" property, this is the number of records returned by the query. I like to use this to determine whether the results returned are what I expect (i.e.: there should only be one Account by a certain company's name), and whether it even exists at all in the org.&lt;/p&gt;

&lt;p&gt;Once you've determined the number of results match what was expected, you can use the JObject as you would any other object using "records". This object works like an array so if there were more than one record returned you could iterate through them to retrieve a value from each. In our case though, we're simply getting the accountId and accountPhone from our first and only record and moving on. These values can be used to programmatically update your database, other Salesforce records, or an ERP.&lt;/p&gt;

&lt;p&gt;The next installment of this series will cover updating our retrieved Account record with the customer's phone number, where ("totalSize" == "1") meaning one Account was retrieved by our query and no further decisions are necessary.&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;If you'd like to catch up with me on social media, come find me over on &lt;a href="https://twitter.com/RachSoderberg"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/rachelsoderberg/"&gt;LinkedIn&lt;/a&gt; and say hello!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>salesforce</category>
      <category>rest</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Integrating C# .NET and Salesforce's REST API</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Thu, 30 Apr 2020 18:47:30 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/integrating-c-net-and-salesforce-s-rest-api-d00</link>
      <guid>https://forem.com/rachelsoderberg/integrating-c-net-and-salesforce-s-rest-api-d00</guid>
      <description>&lt;p&gt;In my previous Salesforce series we learned how to perform authentication, login, run queries, and create, update, or delete records using the Salesforce SOAP API. In this new series we're going to work through similar tasks using the Salesforce REST API because not every technology stack, or development team, is willing and able to handle SOAP requests.&lt;/p&gt;

&lt;p&gt;Today we're going to set up our application's connection to Salesforce, including the creation of our Connected App, and use our application to login through the Salesforce REST API. All of my code examples will be from a C# .NET Core application, but will work in .NET Framework as well, and my Salesforce examples will be using Lightning Experience (Spring 2020 release).&lt;/p&gt;

&lt;h1&gt;Connected App&lt;/h1&gt;

&lt;p&gt;The first step to integrating with the Salesforce REST API is creating a new Connected App within your Salesforce org. I recommend doing this in Test or Development first, before releasing your app into Production! This app will serve as the endpoint your application uses to authenticate with your Salesforce org and allows an admin to grant or restrict permissions for apps' access to data as well as users' access to external apps.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to Setup &amp;gt; Apps &amp;gt; App Manager.&lt;/li&gt;
&lt;li&gt;Click "New Connected App".&lt;/li&gt;
&lt;li&gt;Fill in the required information on the New Connected App form using whatever Connected App Name you'd like, a real Contact Email, and a Callback URL.
The Callback URL can be a dummy URL as we will be using the &lt;a href="https://tools.ietf.org/html/rfc6749#section-4.3" rel="noopener noreferrer"&gt;'resource owner password grant'&lt;/a&gt; - in other words our application will authenticate with Salesforce using a legitimate user's Username and Password.
Check Enable OAuth Settings and select "Access and manage your data (api)" under Selected OAuth Scopes.
  &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwzhr56vdi3ck3ax3rhhf.PNG" alt="New Connected App"&gt;
&lt;/li&gt;
&lt;li&gt;Click Save and then click Continue. &lt;b&gt;Take note of your Consumer Key and Consumer Secret. These cannot be revealed again and are essential for your application to access your org.&lt;/b&gt;
&lt;/li&gt;
&lt;li&gt;As per the warning, don't use the app for several minutes after creation.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;Authenticating From .NET&lt;/h1&gt;

&lt;p&gt;Next we need to create or modify our .NET application and create a few properties to store our login, authentication, and client info:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public const string LoginEndpoint = "https://test.salesforce.com/services/oauth2/token";
    public const string ApiEndpoint = "/services/data/v36.0/"; //Use your org's version number

    private string Username { get; set; }
    private string Password { get; set; }
    private string Token { get; set; }
    private string ClientId { get; set; }
    private string ClientSecret { get; set; }
    public string AuthToken { get; set; }
    public string ServiceUrl { get; set; }

    static readonly HttpClient Client;

    static MyController()
    {
        Client = new HttpClient();
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above getters and setters contain confidential information. These should be stored using a secure method for retrieval during authentication.&lt;/p&gt;

&lt;p&gt;We will build our authentication to the API using the HttpClient class for our asynchronous HTTP callouts, and FormUrlEncodedContent which is required by Salesforce. This can also be done synchronously if you choose by using the Result keyword on any async calls. If you are returned a bad request response, double check that you've used FormUrlEncodedContent correctly.&lt;/p&gt;

&lt;p&gt;Note: If you run into a security error, add the TLS 1.1 or 1.2 protocols to your method or constructor and try to send the request again:&lt;br&gt;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  HttpContent content = new FormUrlEncodedContent(new Dictionary&amp;lt;string, string&amp;gt;
      {
          {"grant_type", "password"},
          {"client_id", ClientId},
          {"client_secret", ClientSecret},
          {"username", Username},
          {"password", Password}
      });

  HttpResponseMessage message = Client.PostAsync(LoginEndpoint, content).Result;

  string response = message.Content.ReadAsStringAsync().Result;
  JObject obj = JObject.Parse(response);

  AuthToken = (string)obj["access_token"];
  ServiceUrl = (string)obj["instance_url"];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Testing our method by printing the result of the response should return the following JSON object containing our authentication token as a string:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "{
        \"access_token\":\"00D630000004mdS!AR0AQHhG_MsU_i5BqeqvimbRa.BP4Oanqn4v9UUedHDk_.BCP6p4dDPnnhZ7Y8nhtra1v2DWuPUOwt.IaDlj_XdnCYLgzIDd\",
        \"instance_url\":\"https://cs43.salesforce.com\",
        \"id\":\"https://test.salesforce.com/id/00D630000004mdSEAQ/00560000003gFPbAAM\",
        \"token_type\":\"Bearer\",
        \"issued_at\":\"1588270529868\",
        \"signature\":\"XFhjeOi/xxL+PoNW7kW1vhp1cgus9OT16fhoFEBEKfs=\"
  }"
  // These values have been modified for security
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you run into an invalid_client_id error, go to Settings and view the Profile for the account you're using to log in. Verify that the new Connected App you've created is checked under Connected App Access.&lt;/p&gt;

&lt;p&gt;The access_token and instance_url values are used to set our AuthToken and ServiceUrl respectively. We will access these values later when we perform queries, create new records, and update existing records.&lt;/p&gt;

&lt;p&gt;In the next post of this series we will use our new authentication token to perform a query and retrieve an Account from our Salesforce org.&lt;/p&gt;




&lt;p&gt;If you'd like to catch up with me on social media, come find me over on &lt;a href="https://twitter.com/RachSoderberg" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/rachelsoderberg/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and say hello!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>salesforce</category>
      <category>rest</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>I "Game-ified" My To-Do List to Help with my Work-Life Balance</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Fri, 20 Mar 2020 20:43:02 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/i-game-ified-my-to-do-list-to-help-with-my-work-life-balance-2m3j</link>
      <guid>https://forem.com/rachelsoderberg/i-game-ified-my-to-do-list-to-help-with-my-work-life-balance-2m3j</guid>
      <description>&lt;p&gt;I hope this blog post finds you well, the world is going through some crazy times and I'm looking forward to us coming out stronger after it's all over. I'm sure many of you are working from home, possibly for the first time ever, for an undetermined amount of time and it can be a struggle learning how to find a quality work-life balance when your work and life may consist of the same studio apartment, bedroom, or home office and computer.&lt;/p&gt;

&lt;p&gt;One trick I've found that's helped me know when to "turn off" work mode is making a small tweak to my To-Do List. Typically my first column is "Today", the second is "This Week", and later columns are things like backlog, done, etc. That first column, although clear in intentions, just wasn't doing the trick for working from home - I would keep adding things as they came up and my stack of things to do "Today" just kept growing and growing.&lt;/p&gt;

&lt;p&gt;And so the "Today's Win Condition" column was born!&lt;/p&gt;

&lt;p&gt;Everyday, first thing in the morning, I spend a few minutes gathering my thoughts and deciding what needs to be done for the day. This includes work tasks as well as any other things I need to complete before my day is done (for instance, laundry or my workout). Once I've checked off each and every one of those things, my day is done! &lt;em&gt;Within reason obviously, it needs to be more than a two hour day.&lt;/em&gt; This leaves me feeling great for having achieved a major goal for the day, broken up into several mini-goals, and at the end of the day I can tell myself "Yes! I won!" and move onto fun hobby-type things.&lt;/p&gt;

&lt;p&gt;I'm sure this idea won't work for everyone, but I thought it'd be a great and fun way to break up the monotony of routine a bit and help anyone who's struggling with knowing when and how to break out of work mode at the end of their day!&lt;/p&gt;




&lt;p&gt;If you'd like to catch up with me on social media, come find me over on &lt;a href="https://twitter.com/RachSoderberg"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/rachelsoderberg/"&gt;LinkedIn&lt;/a&gt; and say hello!&lt;/p&gt;

</description>
      <category>remotework</category>
      <category>workfromhome</category>
      <category>productivity</category>
      <category>worklifebalance</category>
    </item>
    <item>
      <title>Dungeons &amp; Dragons Max Hit Points Calculator</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Fri, 14 Feb 2020 18:03:26 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/dungeons-dragons-max-hit-points-calculator-project-22k</link>
      <guid>https://forem.com/rachelsoderberg/dungeons-dragons-max-hit-points-calculator-project-22k</guid>
      <description>&lt;p&gt;This week I wanted to do something different and share a fun little side project I put together! A bit of backstory: I've recently begun playing Dungeons and Dragons with some friends and think it's awesome, and going through the trouble of learning how to determine my character's HP at each level was some combination of humorous and frustrating. When I figured out the math, I decided to really solidify the concept and save future me some time in the process... and so the D&amp;amp;D Max Hit Points Calculator was born!&lt;/p&gt;

&lt;p&gt;I built the Calculator as a Windows Form Application and it is quite simple and easy to use (and would be a fun learning project for anyone getting into C#). Simply enter your character's current max HP (or 0 if it's a new level 1 character) into "Current Max HP", put your Constitution modifier value into "Const Modifier", and click Roll after selecting the hit die your class was designated to generate your rolled die value. Click Calculate Max Hit Points and voila - the math's been done for you! The "Current Max HP" value will even update, making rolling for multiple levels a snap.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh7gn759qkboptveivrgs.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh7gn759qkboptveivrgs.PNG" alt="Max Hit Points Calculator"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a link to the source code: &lt;a href="https://github.com/rsoderberg/D-D-Max-Hit-Points-Calculator" rel="noopener noreferrer"&gt;D&amp;amp;D Max Hit Points Calculator&lt;/a&gt;. You are welcome to use this project for whatever you'd like (except selling or distributing it, obviously). Feel free to learn with it, copy and tweak it, use it for your own D&amp;amp;D games, or even comment/email me with suggestions (&lt;a href="mailto:r_soderberg@yahoo.com"&gt;r_soderberg@yahoo.com&lt;/a&gt;).&lt;/p&gt;




&lt;p&gt;If you'd like to catch up with me on social media, come find me over on &lt;a href="https://twitter.com/RachSoderberg" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/rachelsoderberg/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and say hello!&lt;/p&gt;

</description>
      <category>project</category>
      <category>hobby</category>
      <category>dnd</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Error: Actions Not Showing Up As Buttons On Lightning Pages</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Mon, 03 Feb 2020 15:31:36 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/error-actions-not-showing-up-as-buttons-on-lightning-pages-4n1e</link>
      <guid>https://forem.com/rachelsoderberg/error-actions-not-showing-up-as-buttons-on-lightning-pages-4n1e</guid>
      <description>&lt;p&gt;Imagine a scenario: You've replaced your URL Hacked buttons with new object-specific actions and dragged them into the Salesforce Mobile and Lightning Experience Actions section part of the Page Layout. You click save, check the object and... your action isn't there? What gives?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdtrgmez5d6g4sf99xu9r.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdtrgmez5d6g4sf99xu9r.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxh4a25bfuk4vorioj16.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxh4a25bfuk4vorioj16.PNG" alt="No Buttons"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The issue is that Quick Actions in the Salesforce Mobile and Lightning Experience Actions simply show in the Chatter tab when Feed Tracking is enabled. It's not made very clear in the help text so many people are finding themselves confused if they haven't actually thought to check Chatter The help text on the Page Layout properties is as follows:&lt;br&gt;
Feed tracking is disabled for this object, but you can still customize actions for Lightning Experience and the mobile app action bar. Actions in this section appear only in Lightning Experience and the mobile app, and may appear in third party apps that use this page layout.&lt;/p&gt;

&lt;p&gt;Only after you've disabled Feed Tracking for the object will your actions display at the top of the object details as expected. So let's go ahead and disabled that so our actions show up where users would expect them.&lt;/p&gt;

&lt;p&gt;Disable Feed Tracking:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to Setup and search "Feed Tracking"&lt;/li&gt;
&lt;li&gt;Select the object you'd like to stop tracking from the list on the left&lt;/li&gt;
&lt;li&gt;Uncheck the "Enable Feed Tracking" checkbox
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flxyqmqhdjhq5am850gfe.PNG" alt="Feed Tracking"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Navigate back to a record on your object detail page and confirm that your actions now show as expected. If you don't see them, double check the Page Layout and whether you placed the correct action in Salesforce Mobile and Lightning Experience Actions and that you don't already have too many actions selected for the section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkfkd4zji4eokkwhr3aqn.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkfkd4zji4eokkwhr3aqn.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;If you'd like to catch up with me on social media, come find me over on &lt;a href="https://twitter.com/RachSoderberg" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/rachelsoderberg/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and say hello!&lt;/p&gt;

</description>
      <category>salesforce</category>
      <category>lightning</category>
      <category>quickaction</category>
    </item>
    <item>
      <title>Replace "URL Hacking" With Salesforce Actions</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Wed, 22 Jan 2020 16:45:36 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/replace-url-hacking-with-salesforce-actions-4k54</link>
      <guid>https://forem.com/rachelsoderberg/replace-url-hacking-with-salesforce-actions-4k54</guid>
      <description>&lt;p&gt;For many years Salesforce allowed (though may not have suggested) the auto-filling of fields during object creation using a technique called "URL Hacking". This technique involved creating a Custom List Button on an object, then adding a URL with the ids and values to be filled:&lt;br&gt;
&lt;i&gt;/a03/e?&amp;amp;retURL={!Case.Id}&amp;amp;CF00N2C000001PDmC_lkid={!Case.Account}&amp;amp;CF00N2C000001PDm7={!Case.Contact}&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately with Lightning Experience this feature has been deprecated as browser tabs were replaced with tabs and sub-tabs housed within a single Salesforce browser window.&lt;/p&gt;

&lt;p&gt;All is not lost, though!&lt;/p&gt;

&lt;p&gt;Actions are Salesforce's solution to this problem - although they are slightly more time-consuming to set up, they are more robust and provide better functionality than a URL-hacked button. There are currently two kinds of actions available:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Global actions can be placed and used from any of your org's objects, therefore they cannot access any object-specific information such as record ids. Global actions are best for automatically creating new records, sending emails, or logging calls.&lt;/li&gt;
&lt;li&gt;Object-specific actions can only be added to the selected object's page layout, providing access to fields on the selected object such as record ids and field values. To replace URL-hack buttons we want to use object-specific actions because they most closely resemble this functionality.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this tutorial we're going to walk through creating an object-specific action since that is the most likely choice for the topic:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Click Setup and search "Object Manager".&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RozSXWAF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hhvbmi9wmv1z05cxlxlz.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RozSXWAF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hhvbmi9wmv1z05cxlxlz.PNG" alt="Search Object Manager"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the parent object in the list (this is the one you're placing the Action on, not the object you're creating).&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8JDYDlU1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/39kmabdlzsdtmfxkdls3.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8JDYDlU1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/39kmabdlzsdtmfxkdls3.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the left-hand toolbar click "Buttons, Links, and Actions".&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OKzEKkJN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vg2hb4ymtdj3zzfow2eb.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OKzEKkJN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vg2hb4ymtdj3zzfow2eb.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click "New Action" in the top right corner of the window.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xzOsAxTM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/e0vfwu4mjlz9z2l6kmvk.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xzOsAxTM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/e0vfwu4mjlz9z2l6kmvk.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the New Action screen update the Action Type to "Create a Record", set Target Object to the object you want to create, and create or select a Label. The Name field will auto-fill based on your Label selection. My Action is set up to create a new RMA, which is a custom object in my company.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NDaqk2Bi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/q3zanf6tikcrmcr8xyw2.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NDaqk2Bi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/q3zanf6tikcrmcr8xyw2.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next you will see the Page Layout screen, which works similarly to any object Page Layout. Choose the fields you'd like the user to fill in (or be auto-filled) on the Create New page dialog by dragging them onto/off of the white workspace. Note: Salesforce suggests keeping the number of fields at a minimum to avoid overwhelming your users!&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HZS0E010--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7mna2xnj51evq94roxmg.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HZS0E010--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7mna2xnj51evq94roxmg.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Saving your page layout will redirect you to the Action details page. To select fields to auto-fill and provide their values, click "New" in the Predefined Field Values related list.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NOGbQjYZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/snjp5s4nq7n2es3fiowc.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NOGbQjYZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/snjp5s4nq7n2es3fiowc.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the New Predefined Field Value screen, select the Field you'd like to have auto-filled from the Field Name drop-down. In the formula editor, either enter a hard-coded value or most commonly a field value from the parent object.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XkMrT8JV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/gmhuufp9ew5lb8icgqbq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XkMrT8JV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/gmhuufp9ew5lb8icgqbq.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repeat step 8 for all of the fields you want filled.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EvZQh2X1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xy0hyv3h3b5zhgkpxep8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EvZQh2X1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xy0hyv3h3b5zhgkpxep8.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The final step is to add the new Action to the page layout of the parent object. Navigate to the Page Layout and drag your action into the Salesforce Mobile and Lightning Experience Actions from the Mobile &amp;amp; Lightning Actions selection.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MR7i3VR6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/uonb06p5tt0b10h54z34.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MR7i3VR6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/uonb06p5tt0b10h54z34.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirm the Action shows up correctly on the object detail page*. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nJR2_gSg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/482yvhc11mkkk6rs2z65.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nJR2_gSg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/482yvhc11mkkk6rs2z65.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;*If your Action isn't showing up correctly on the object read the next tutorial in this series titled "Error: Actions Not Showing Up As Buttons On Lightning Pages" (coming soon)&lt;/p&gt;




&lt;p&gt;If you'd like to catch up with me on social media, come find me over on &lt;a href="https://twitter.com/RachSoderberg"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/rachelsoderberg/"&gt;LinkedIn&lt;/a&gt; and say hello!&lt;/p&gt;

</description>
      <category>salesforce</category>
      <category>lightning</category>
      <category>quickaction</category>
    </item>
    <item>
      <title>Hello! I've Missed You All!</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Mon, 13 Jan 2020 20:04:14 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/hello-i-ve-missed-you-all-14pa</link>
      <guid>https://forem.com/rachelsoderberg/hello-i-ve-missed-you-all-14pa</guid>
      <description>&lt;p&gt;I feel like it's been awhile since I last wrote a post or article - nearly four months to be exact! I felt like writing a brief "re-introduction" since I've been inactive for a stretch of time; I've still been reading everyone's awesome work and keeping up with that, but haven't been creating any new content of my own.&lt;/p&gt;

&lt;p&gt;Anyways, to avoid rambling, I'm back! I took some time off of writing because it was becoming a source of anxiety for me to meet my "write an article every week" goal. At work I've been going through a period where I have been doing more maintenance and Salesforce admin-type tweaks for converting to Lightning than producing new work or resolving crazy bugs, so I was finding myself at a loss for what to write about. Instead of stressing, I put the articles aside for awhile and accepted that it's okay to not meet a yearly goal if it's become a hindrance.&lt;/p&gt;

&lt;p&gt;I don't know whether I'll be writing an article every single week, every other week seems more reasonable for the time being. I already have some great article ideas for those who are following me for my Salesforce content - I'll be digging into an awesome project soon as we finish Lightning conversion at my company, and I plan to bring you all along for the ride! Salesforce will probably be my main focus going forward, but you can expect to see some occasional C# .NET content as well. Perhaps even a sprinkling of life lessons. :)&lt;/p&gt;

&lt;p&gt;So... yea, it's great to be back! I'm happy to see everyone still writing, and if you actually made it this far just know that you're awesome and I hope you have a fantastic new year!&lt;/p&gt;

&lt;p&gt;Keep on writing and learning!&lt;br&gt;
Rachel&lt;/p&gt;




&lt;p&gt;If you'd like to catch up with me on social media, come find me over on &lt;a href="https://twitter.com/RachSoderberg"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/rachelsoderberg/"&gt;LinkedIn&lt;/a&gt; and say hello!&lt;/p&gt;

</description>
      <category>hello</category>
      <category>greetings</category>
    </item>
    <item>
      <title>Update Salesforce Fields With A Button Click (Salesforce Classic)</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Mon, 23 Sep 2019 20:07:56 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/update-salesforce-field-with-a-button-click-3fkj</link>
      <guid>https://forem.com/rachelsoderberg/update-salesforce-field-with-a-button-click-3fkj</guid>
      <description>&lt;p&gt;Before I begin, I would like to note that soon the information in this post will be outdated. Salesforce is in the process of phasing out Salesforce Classic and moving everyone to Lightning Experience, and with this they are phasing out JavaScript buttons and actions. I plan to release a follow-up post that goes into the process of rebuilding your JavaScript buttons using the Lightning Custom Components, their new preferred method of performing the same tasks, as I go through the process of updating them in my company's org.&lt;/p&gt;

&lt;h1&gt;Create A Button&lt;/h1&gt;

&lt;p&gt;Salesforce has two different types of objects - Standard and Custom. Standard objects come with Salesforce straight out of the box while Custom objects are created by an org's administrator. Below are the steps to create a new button for both types of objects:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Standard Objects&lt;/b&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click Setup and in the left toolbar find and expand Build &amp;gt; Customize &amp;gt; {Your Object}.&lt;/li&gt;
&lt;li&gt;Under {Your Object} click "Buttons, Links, and Actions".&lt;/li&gt;
&lt;li&gt;Click New Button or Link.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;b&gt;Custom Objects&lt;/b&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click Setup and in the left toolbar find and expand Build &amp;gt; Create &amp;gt; Objects.&lt;/li&gt;
&lt;li&gt;Find and click {Your Object} in the list of Custom objects.&lt;/li&gt;
&lt;li&gt;Scroll down to the Buttons, Links, and Actions section and click New Button or Link.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From this point on, the steps should be the same for both Standard and Custom objects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fill in the Label and the Name should auto-populate. Include a Description if desired.&lt;/li&gt;
&lt;li&gt;Choose your desired display type. This may be a link within a Custom field, a button on your Object Detail page, or a button that will show up on a Related List.&lt;/li&gt;
&lt;li&gt;"Execute JavaScript" is your selection for the behavior, which will trigger a warning for compatibility issues with Lightning Experience. We are going to ignore this for now, and update later when we switch to Lightning.&lt;/li&gt;
&lt;li&gt;Select "OnClick JavaScript" for the Content Source.&lt;/li&gt;
&lt;li&gt;Save your new button.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;Update a Field With JavaScript&lt;/h1&gt;

&lt;p&gt;You've got a new button all set up and ready to go - now all that's left is adding the functionality to update a field. If you are familiar with JavaScript this will be a breeze, but you'll still be okay if not! (I am not well-versed in JS, so I apologize if any of my terminology is wrong and welcome any corrections!)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If you saved and closed your button, open it back up from the Buttons, Links, and Actions section of your object and click Edit.&lt;/li&gt;
&lt;li&gt;The first required step is adding a reference to the toolkit at the top of the function Content Editor:
{!REQUIRESCRIPT("/soap/ajax/19.0/connection.js")}.&lt;/li&gt;
&lt;li&gt;Instantiate a new SObject, passing in the name of your Object.&lt;/li&gt;
&lt;li&gt;Set your new SObject.id to your Object.Id field.&lt;/li&gt;
&lt;li&gt;Update the SObject.FieldName of each field you want to make a modification to. You can use the Field Type and Insert Field dropdowns to find specific fields from your objects.&lt;/li&gt;
&lt;li&gt;End the file with the following:result = sforce.connection.update([Your SObject]);&lt;/li&gt;
&lt;li&gt;Check Syntax to ensure your JavaScript is functionally correct, then Save.&lt;/li&gt;
&lt;li&gt;Add your new button to the Page Layout of your object, and click it to test!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The above steps may have been confusing on their own, so here is a sample from one of the buttons on my org's Custom RMA object:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  {!REQUIRESCRIPT("/soap/ajax/19.0/connection.js")} 

  var rma = new sforce.SObject("RMA__c");
  rma.id = "{!RMA__c.Id}";
  rma.Printed__c = new Date().toISOString();
  rma.Printed_By__c = "{!User.Name}";

  result = sforce.connection.update([rma]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I hope this brief introduction to updating Salesforce fields on button click has inspired you to add some extra functionality to your Salesforce workflows. Keep an eye open for my Lightning Experience buttons update in the coming weeks!&lt;/p&gt;




&lt;p&gt;If you'd like to catch up with me on social media, come find me over on &lt;a href="https://twitter.com/RachSoderberg"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/rachelsoderberg/"&gt;LinkedIn&lt;/a&gt; and say hello!&lt;/p&gt;

</description>
      <category>salesforce</category>
      <category>button</category>
    </item>
    <item>
      <title>Recommend A Software Project Management Book?</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Thu, 12 Sep 2019 20:29:39 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/recommend-a-software-project-management-book-95m</link>
      <guid>https://forem.com/rachelsoderberg/recommend-a-software-project-management-book-95m</guid>
      <description>&lt;p&gt;Hello! I'm looking for a few great books to improve my skills at Software Project Management. Essentially, I want to learn more about building up a project from scratch - I'm hoping for something that covers information &amp;amp; requirements gathering and project conception, but would welcome any resources you have found to be helpful on the topic.&lt;/p&gt;

&lt;p&gt;Thanks all!&lt;/p&gt;

</description>
      <category>help</category>
    </item>
    <item>
      <title>How I Am Getting Out From Under My Student Debt</title>
      <dc:creator>Rachel Soderberg</dc:creator>
      <pubDate>Mon, 09 Sep 2019 20:30:05 +0000</pubDate>
      <link>https://forem.com/rachelsoderberg/how-i-am-getting-out-from-under-my-student-debt-h8e</link>
      <guid>https://forem.com/rachelsoderberg/how-i-am-getting-out-from-under-my-student-debt-h8e</guid>
      <description>&lt;p&gt;Greetings! I will start out this post by saying I am &lt;em&gt;not&lt;/em&gt; a qualified financial advisor. I'm not even particularly well studied in the realm of finances. All of what I am about to share has been read by me somewhere online, advised to me by a friend, or discovered through trial and error.&lt;br&gt;
&lt;b&gt;Use what you read here at your own discretion!&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Alright, now that you can't sue me, let's get into it!&lt;/p&gt;

&lt;h1&gt;Background&lt;/h1&gt;

&lt;p&gt;You may know a little about me through my profile or social media, but I'll introduce myself with a little more detail so you can get an idea of where I'm coming from. I'm going to share some specifics of my financial information, so if that makes you uncomfortable this is your easy out!&lt;/p&gt;

&lt;p&gt;I went to college in Portland, Oregon for five years - about two of them were spent in Community College (some of which was "figuring out what I wanted to be when I grow up" and some was earning my Transfer Associate Degree). The rest was spent at Oregon Institute of Technology, a local school with a good curriculum and reasonable term charges, where I earned a Bachelor of Software Engineering.&lt;/p&gt;

&lt;p&gt;You may be curious why a Bachelor's degree took me five years - short story is that the school told me there would be no problem transferring in during the Winter term, but they were wrong. All of the course cycles begin in Fall so I ended up essentially a year behind, to my financial detriment. I almost did not graduate because I ran out of funds at the start of year #5 - I was blessed enough to have a friend who believed in me and was willing to cosign for a significant private student loan to finish out my last year.&lt;/p&gt;

&lt;p&gt;I did not make the best decisions during my time in school. I worked some part time jobs, but never enough to fully support myself without the financial aid, and I made numerous poor decisions with my credit cards. Hard lessons were learned, that's for sure!&lt;/p&gt;

&lt;p&gt;When I graduated in May 2018 I was deeply in the hole. I had just over $17k in credit card debt and around $93k in debt from college ($12k of which was a high-interest private loan).&lt;/p&gt;

&lt;h1&gt;Digging Out&lt;/h1&gt;

&lt;p&gt;The massive pile of debt in front of me was daunting and I knew it would take some time to free myself from it - my goal was five years, to be exact. I came up with that magic timeline by dividing the total amount of debt by my expected leftover income. I don't have any kids and I live with my partner so most expenses are split evenly between us, lowering my cost of living a great deal. I figured I'd have about $1,800 left over most months to go into my debt.&lt;/p&gt;

&lt;p&gt;110,000/1,800 = 61.11/12 = 5.1 years (not accounting for interest)&lt;/p&gt;

&lt;p&gt;This leads me to the first technique: &lt;b&gt;Pay more than your minimum balance, even just a small amount.&lt;/b&gt; When you pay only the minimum, especially on high-interest loans, you may only be paying a portion of the interest each month and never anything into the actual balance. This means the loan will continue to grow... and grow... and grow... even though your hard-earned money is going into it every month.&lt;/p&gt;

&lt;p&gt;I knew I needed to form a strategy to make all of my payments as effective as possible. First, I expanded the budget spreadsheet I'd been halfheartedly using. Technique number two: &lt;b&gt;A budget is essential for effective debt pay down.&lt;/b&gt; I'd heard of a couple of techniques - the snowball method and the avalanche method - and considered which would be best for me in my situation and mental state:&lt;/p&gt;

&lt;p&gt;Snowball Method:&lt;br&gt;
Pay off your debt from the smallest balance to the largest, regardless of interest rate. Whenever a debt is paid off, that minimum payment is rolled into the next smallest balance to make your payments larger. This method is recommended for people who need a "quick win" and will be motivated by seeing debts disappear. &lt;a href="https://www.daveramsey.com/blog/how-the-debt-snowball-method-works"&gt;Dave Ramsey&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Avalanche method:&lt;br&gt;
Ignore debt balances and instead pay off debts in order of highest interest rate to lowest. Ideally, this will allow you to pay off your total debt much more quickly because the amount of interest you pay over the entire period can be much less as the highest interest culprits were removed first. As with the snowball method, roll up the minimum payments as you pay debts off and push it towards the next highest interest debt. Using this method is great for people who are patient and driven by a long-term plan. &lt;a href="https://www.nerdwallet.com/blog/finance/what-is-a-debt-avalanche/"&gt;Nerd Wallet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have no issues with maintaining enthusiasm through slow wins, so I took the long route via &lt;b&gt;the avalanche method&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;The credit cards went first. I paid only the minimum on my student loans and threw all of my spare money into the credit card debt. A happy side result: my credit score started going up! I was approved for a couple of 0% APR for 12-18 months offers and balance transferred the remaining balances over. This left me with zero interest-gaining credit card debt in early 2019! A victory! Riding high on this small win, I began shoveling away at the student debt.&lt;/p&gt;

&lt;p&gt;The first loan I wanted to dig into was the private loan my friend so kindly co-signed on. With only making minimum payments since it became active, it was up another one or two thousand dollars because the interest rate was a whopping 11.13%! That's about as high as some lower rate credit cards. I leveraged a couple more 0% APR balance transfer offers as my credit standing grows and paid off that loan in June 2019.&lt;/p&gt;

&lt;p&gt;I'm currently continuing to pile away at the student loans have picked up a lot of momentum as I got into the swing of things - my cost of living is even lower than I originally anticipated so I modified my pay off goal to three years (accounting for interest this time). By the end of the year I'll have put around $35k into debt and my spreadsheet has a lovely forecast of 2.9 years!&lt;/p&gt;

&lt;h1&gt;Strategies&lt;/h1&gt;

&lt;p&gt;Debt is a terrible thing to be piled under, and it can feel hopeless. But there are a few methods you can use to get yourself out of it more quickly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pay more than your minimum balance, even just a few dollars.&lt;/li&gt;
&lt;li&gt;Create a budget and list all of your debt details including interest rates and balances.&lt;/li&gt;
&lt;li&gt;Choose a method to focus your payments more effectively. Most common are the Snowball Method and the Avalanche Method.&lt;/li&gt;
&lt;li&gt;If possible, leverage offers for 0% APR for 12-18 months to remove high-interest debts early. Do not let these lapse outside of the promotional period!&lt;/li&gt;
&lt;li&gt;Re-consolidate for a lower interest rate. This may not work for all situations, it was not ideal for mine, but it is a valid option to consider to reduce the number of payments per month and lower your interest rate.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once again, I am not a financial advisor. What I've learned is from reading and my own trial and error, so use any advice here at your own discretion. I am simply sharing my story in hopes it will encourage or inspire someone else.&lt;/p&gt;




&lt;p&gt;If you'd like to catch up with me on social media, come find me over on &lt;a href="https://twitter.com/RachSoderberg"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/rachelsoderberg/"&gt;LinkedIn&lt;/a&gt; and say hello!&lt;/p&gt;

</description>
      <category>debt</category>
      <category>graduates</category>
      <category>college</category>
      <category>finances</category>
    </item>
  </channel>
</rss>
