Monthly Archives: April 2018

Warning: Can’t call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method. – ReactJs

Hi everyone,

This is just a quick post, mostly for my future reference but hopefully it will help someone else out as well. I ran into the following error when invoking a callback in a child component:

Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.

This is generally a result of updating the state of a child component after the parent component has hidden it.

e.g. the child component calls a prop function which hides the child component. On the line after the prop function call the child component attempts to set a state variable.

Issue

In my case, it was because I was setting the loading state of a child component to false after performing a successful fetch. Normally this would be fine however I had hidden the child component via the parent component’s prop callback after the successful response was confirmed.

  • (Child Component): Set loading state to true.
  • (Child Component): Call API
  • (Child Component): After retrieving payload, invoke parent component’s prop function and pass it the payload
  • (Parent Component): Process payload. In render, the new payload hides the child component
  • (Child Component): Attempts to set loading state to false Error: can’t change state now that the component is no longer mounted

Solution

To get around it, I had to ensure that I didn’t invoke the parent’s callback (or unload the child) until after the child’s state had been set.

  • (Child Component): Set loading state to true.
  • (Child Component): Call API
  • (Child Component): Retrieve payload, set loading state to false place state change before parent callback is invoked
  • (Child Component): Invoke parent component’s prop function and pass it the payload
  • (Parent Component): Process payload. In render, the new payload hides the child component

Now that the child component state is modified before it is unmounted there isn’t an issue. The easiest way that I’ve found to debug errors like this is to set breakpoints (either hardcoded or in the console) to ensure that everything is being invoked in the expected order.

If you need any more info please let me know!

Thanks,
Chris

Advertisements

Include UserId in Login Response (Token) – Web API 2

Hi everyone,

A quick post on how to include the user’s id in your login response when using Web API 2.

The default response to the /Token request is as follows:

{
“access_token”: “xxxxxxxxxxxxx_xxxx”,
“token_type”: “bearer”,
“expires_in”: 1209599,
“userName”: “test@test.com”,
“.issued”: “Mon, 23 Apr 2018 06:08:03 GMT”,
“.expires”: “Mon, 07 May 2018 06:08:03 GMT”
}

Once the changes below have been made the response will include a userId field:

{
“access_token”: “xxxxxxxxxxxxx_xxxx”,
“token_type”: “bearer”,
“expires_in”: 1209599,
“userName”: “test@test.com”,
“.issued”: “Mon, 23 Apr 2018 06:08:03 GMT”,
“.expires”: “Mon, 07 May 2018 06:08:03 GMT”,
“userId”: “xxxxxxx”
}

There are three very small changes required in order to add this functionality.

First, add an additional argument to CreateProperties in ApplicationOAuthProvider.cs

public static AuthenticationProperties CreateProperties(string userName, string userId)
{
IDictionary data = new Dictionary
{
{ "userName", userName },
// Add
{ "userId", userId }
};
return new AuthenticationProperties(data);
}

Pass userId to CreateProperties in ApplicationOauthProvider.

// ApplicationOAuthProvider.cs > GrantResourceOwnerCredentials
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType);
ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
CookieAuthenticationDefaults.AuthenticationType);

// Add user id
AuthenticationProperties properties = CreateProperties(user.UserName, user.Id);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);

Pass userId to CreateProperties in AccountController.

// AccountController.cs > GetExternalLogin
if (hasRegistered)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);

ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager, OAuthDefaults.AuthenticationType);
ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
CookieAuthenticationDefaults.AuthenticationType);

// Add userid
AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName, user.Id);
Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);

Module build failed: Error: ENOENT: no such file or directory, open – Windows

Hi everyone,

I’ve been mucking around with React over the last couple of days. I ran into the following error while trying to build:

Module build failed: Error: ENOENT: no such file or directory, open ‘c:…Form.js’
at Error (native)

It took a while to sort this one out but I eventually came across a solution on github:

npm rebuild node-sass

Thanks to xzyfer for posting in the following github thread: https://github.com/sass/node-sass/issues/1579#issuecomment-227661284

There’s a whole heap of info in that thread so be sure to check it out.

Thanks,
Chris

Cannot attach the file ‘C:…database.mdf’ as database x – Entity Framework

Hi everyone,

I ran into the following error when attempting to run ‘update-database’ on an initial migration:

Cannot attach the file ‘C:Users…App_Dataaspnet-…115933.mdf’ as database ‘aspnet-…15933’

The solution to this one is pretty easy, remove the initial catalog property from your connection string.

…33.mdf;Initial Catalog=aspnet…

This is apparently caused by issues with EntityFramework and multiple projects in the same database. See the following stackoverflow answer for more info: https://stackoverflow.com/a/20176660/522859

Retrieving User Id in Web API 2 Controller – .NET

Hi everyone,

Just a quick post on how to retrieve the current user’s id in a Web API 2 controller:

var userId = RequestContext.Principal.Identity.GetUserId();

Note that you’ll need the following using statements:

using Microsoft.AspNet.Identity;
using System.Web.Http;

Thanks to the following stackoverflow post for the info: https://stackoverflow.com/a/21618056/522859

Git Ignore Template for .NET

Hi everyone,

A sample .gitignore file for if you’re working with .net:

*.cache
*.dll
*.exe
*.pdb
/build/
*.suo
*.user
_ReSharper.*/
*.sdf
*.opensdf
*.tlog
*.log
TestResult.xml
*.VisualState.xml
Version.cs
Version.h
Version.cpp

Also, if you happen to have added some files you didn’t mean to:

git rm –cached file_you_dont_want.pdb
git commit -m “Remove pdb file”

Thanks to these stackoverflow posts for the info:
https://stackoverflow.com/a/8675415/522859
https://stackoverflow.com/a/11629271/522859

Import an Existing Project to BitBucket

Hi everyone,

Today I needed to import an existing project to Bitbucket. The documentation is really good, but just in case you have trouble finding it:

  1. Navigate to the root directory of your project.
  2. Run the following commands in terminal/command prompt:
    git init
    git add –all
    git commit -m “Initial Commit”
  3. Login to Bitbucket and create repository.
  4. Locate the clone URL (left menu) e.g. https://email_address.bitbucket.domain:7999/project_name/repo.git
  5. Upload your files:
    git remote add origin https://email_address.bitbucket.domain:7999/project_name/repo.git
    git push -u origin master

    Check out the following link for more info: https://confluence.atlassian.com/bitbucketserver/importing-code-from-an-existing-project-776640909.html