How to Check with SharePoint JSOM if File or Folder Exists

Here’s a code snippet showing how to use SharePoint’s JavaScript Object Model (JSOM) to determine whether a file or folder exists:

var ctx = SP.ClientContext.get_current();

// Could also call getFileByServerRelativeUrl() here. Doesn't matter.
// The way this works is identical for files and folders.
var folder = ctx.get_web().getFolderByServerRelativeUrl("/path/to/folder");

ctx.load(folder, "Exists", "Name");

ctx.executeQueryAsync(
   function() {
      if (folder.get_exists()) {
         // Folder exists and isn't hidden from us. Print its name.
         console.log(folder.get_name());
      }
      else {
         console.log("Folder exists but is hidden (security-trimmed) for us.");
      }
   },
   function(s, args) {
      if (args.get_errorTypeName() === "System.IO.FileNotFoundException") {
         // Folder doesn't exist at all.
         console.log("Folder does not exist.");
      }
      else {
         // An unexpected error occurred.
         console.log("Error: " + args.get_message());
      }
   }
);

The behavior of the client-side object model is slightly different depending whether the file or folder truly doesn’t exist or is just being hidden from us due to security-trimming.

The code snippet above takes this distinction into account and shows you how to check for both conditions.

You can also issue a CAML query against a document library (if that’s where your file/folder lives) to see if an item representing your file/folder exists, but the above snippet is intended to demonstrate the procedure for actual SP.File and SP.Folder objects.

My Top 5 Sites for Finding Remote Development Work

If you’ve ever tried searching for remote work as a developer or designer, you know there’s a TON of garbage to sort through and a lot of worthless sites and job postings out there.

The good news is I’ve been finding remote work online for over six years now, and I’ve learned which sites and strategies tend to produce the best results.

But before I list the sites I recommend, I want to say that I specifically do NOT recommend the “bidding” sites like Freelancer, Elance, oDesk (now called Upwork), Fiverr, etc. Strictly speaking, it’s not impossible to find decent work on those sites, but the odds are against you. The rates tend to be ultra-low and the projects not defined very thoroughly. I don’t use those sites, and I’ve never needed to.

Recruiter Saturation Metric

One metric I’ve included for each of the sites below is what I call “recruiter saturation.” The levels I use are low, medium, and high. The higher the level, the more recruiters use the platform to post jobs they’re trying to staff (typically jobs they found elsewhere and are re-posting to be more accurate).

A higher recruiter saturation isn’t necessarily bad – just good to be aware of so you can account for it. A topic I’m saving for another time is how to find the original job posting (if there is one) for a recruiter-posted job so you can apply directly if you want to. I’ve got a few techniques to help with that.

And now, without further adieu, here’s the list of sites.

StackOverflow Careers

StackOverflow is really good but does require a verification process to prove you’re a real developer. The verification process requires that you either (1) be invited by someone StackOverflow already trusts, or (2) send them links to code you’ve published – such as on GitHub – and they’ll judge you based on activity (commits, pull requests, etc.) and/or code quality. The good news is this keeps a lot of low-quality developers out of the mix and keeps rates fair.

If you can pass the verification process, it’s worth it because the job postings here tend to be good. Since they’re posted directly to StackOverflow, the location filter (to find jobs with a remote/telecommuting option) is actually accurate. Also, the employers here tend to view developers with more respect than on other job sites.

Recruiter Saturation: Low

Authentic Jobs

This is a good site for finding front-end work (UX, design, JavaScript, etc.) though I occasionally see back-end work on there too. I’ve even seen projects around SharePoint and other collaboration/CMS systems.

I haven’t used this site yet to find work, but I did use this site to hire a web designer a few years back. The candidates I heard from were all decent and all had standard market rates.

The search filters don’t directly allow for a remote/telecommuting option, but they do allow for “Freelance” and “Contract” options. When you combine the two, you tend to see remote opportunities pop up in the results. From what I’ve seen, the postings are usually original and pretty good – not the generic kind of posts you see re-posted by tons of recruiters on other sites.

Recruiter Saturation: Low to Medium (I’ll occasionally see a few posts from “CyberCoders” or similar firms)

We Work Remotely (by 37signals)

This used to be known as the “37signals Job Board” but was renamed a while back to “We Work Remotely.”

The good news is this site lists only remote jobs, so filtering on “remote only” or something similar isn’t necessary. There’s even a link you can click as a job hunter to report postings that erroneously say they’re remote when they’re really not. Controls like that keep the quality high.

The bad news is if you specialize in the Microsoft stack, you won’t find much here. The postings tend to lean more towards MEAN, LAMP, Ruby on Rails, etc. But if you’re into those, it’s a good place to find gigs.

Recruiter Saturation: Low

FlexJobs

Almost everyone knows the major down-side of this one: it costs money! HOWEVER, if you stay on the home page for several minutes and don’t do anything, you’ll almost always get a popup chat window offering you a steep discount, and then it becomes worth considering (because lining up even one gig would get you a good ROI). As an example, it cost me around $40 (with the discount) to sign up for a whole year, and I use this site a lot because it legitimately saves me time.

The premise of the site is they pre-qualify (to a certain extent) the jobs they list, and the jobs all offer flexible work options like weird hours, telecommuting, etc. The idea – which mostly works – is you save a lot of time sorting through garbage because they do that part for you. The result is a lot of medium-quality (and a few high-quality) gigs. They do indeed weed out a lot of the low-quality garbage.

However, there are a couple of downsides. One is the site’s popularity. Because the audience is large, a lot of large companies who offer “mill” type jobs (many applicants, not-so-great pay) post to the site simply for the exposure. Once you identify those, they’re easy to weed out. Another downside is the vetting process isn’t fool-proof. There are jobs sometimes labeled as “All Telecommute” that aren’t. They’re posted by recruiters, for example, who say within the description (usually near the bottom) that you must work onsite.

Recruiter SaturationMedium to High (depending on category/industry)

Indeed

You may be surprised I listed this one because it’s one of those pesky “job aggregator” sites.

Believe me, Indeed does have a LOT of garbage, especially when it comes to finding remote work. BUT… there is a way you can eliminate much of that and actually find some decent gigs.

The trick is to frame your search properly. And forget the “Location” filter that Indeed offers. It sucks and isn’t necessary anyway.

Let’s say you’re looking for remote SharePoint developer jobs. You might try a search like “SharePoint developer remote,” right?

With Indeed, about 30% of the results you get back will be legitimate remote gigs. The rest will come back as remote because there’s wording like “no remote workers” in the description. What I do is add a few qualifiers to my query so I end up with something like this:

sharepoint developer remote -“no remote” -“onsite only” -“does not allow remote”

Now the percentage of legitimate remote gigs jumps from 30% to somewhere near 60%. That’s a much better number to work with, and I’ve actually found a few remote gigs on Indeed by doing that. I would typically also add “-W2 only” because I don’t take W2-only contracts, but that may not apply in your case and that’s fine.

The downside with Indeed is it’s an aggregator. There’s a lot of garbage even with smarter search queries. Do your due diligence. For example, if you see a company name you don’t recognize, look it up on Google. See where it’s based, whether it’s a recruiting firm, whether it’s been reviewed on Glassdoor, etc.

Recruiter SaturationHigh (as in “off the scale” high)

Conclusion

So that’s my list. I sometimes use Craigslist too but very rarely. It only works as well as it does because I live near Denver, and Denver is a good place to find startups and smaller companies who use remote workers.

If you know of a good site that I missed, please comment and let me know! Spam comments or attempts to promote your own site will be moderated appropriately.

New Blog Name, New Focus

If you follow this blog at all, you might have noticed that early this year I published a post saying I was moving away from SharePoint and back into general software/app development.

But SharePoint is like quick sand. It sucks you back in. And the more you struggle, the further you sink as your energy wanes.

So I ended up sticking with SharePoint a while longer than I thought, and I deleted the blog post since it was no longer relevant.

Now fast-forward to August 7, 2015.

SharePoint is now only 50% of the project work I do on a regular basis. That’s kind of like having the upper half of your body above water while a shark is gnawing on your legs. As ridiculous as it sounds, that’s an improvement and a sign that things are moving in the right direction.

New Blog Name

Since I’m no longer just “a SharePoint guy”, I renamed my blog in celebration and recognition of that change.

The new blog name is yield return post;, a name which I fear only hard-core C# developers will fully appreciate. Nonetheless, I think it’s clever and am sticking with it. I could’ve gone all nerd-pop-culture on you and called it “The TARDIS” or something, but I thought better of it.

New Focus

The focus of this blog will be much broader going forward. Rather than focusing heavily on SharePoint, I’ll start branching out into other development topics – C#, Knockout JS, responsive design, iOS development, and whatever else I feel like writing about. I also plan to cover general IT topics and issues relating to job seeking and recruiting.

I’m as much a writer as I am a developer, and I’m looking forward to writing about more than SharePoint for a change!

What about SharePointTapRoom.com?

All of my existing content is still here and I’ll still post things about SharePoint occasionally, so if you arrived here via my sharepointtaproom.com domain looking for SharePoint content, then don’t worry. Your trek was not in vain.

However, be warned that sharepointtaproom.com will only work until November 9, 2015. After that, you’ll need to use yieldreturnpost.wordpress.com to visit this blog!

This is a big change, but it’s a good one and I’m excited about it!

Nested “Include” clauses with SharePoint JSOM API

Recently I needed to load properties two levels deep when using the JSOM (JavaScript Object Model) API in SharePoint 2013. Since it took me a while to find the syntax for it, I figured I’d save others the trouble and just put it right here.

var ctx = SP.ClientContext.get_current();
var folder = ctx.get_web().getFolderByServerRelativeUrl('/server-relative-path/to/folder');
var subfolders = folder.get_folders();

// Here are the nested "Include" clauses. The first loads the
// 'Name' and 'Files' properties of each SP.Folder object in
// the subfolders collection. The second goes a level deeper
// and loads the 'Name' property of each file in the 'Files'
// collection.
ctx.load(subfolders, 'Include(Name, Files.Include(Name))');

ctx.executeQueryAsync(
   function() {
      var folderLooper = subfolders.getEnumerator();
      while (folderLooper.moveNext()) {
         var subfolder = folderLooper.get_current();
         var fileLooper = subfolder.get_files().getEnumerator();
         while (fileLooper.moveNext()) {
            var file = fileLooper.get_current();

            // This line would throw a 'property or field not initialized'
            // exception if I hadn't used the nested Includes above to load
            // the 'Name' property of each file in the collection.
            console.log(file.get_name());
         }
      }
   },
   function(sender, args) {
      alert('Error: ' + args.get_message());
   }
);

Making a SharePoint 2013 Workflow Wait for Document Check-In

I was working on a SharePoint 2013 workflow the other day and turned on the “Start workflow automatically when an item is created” setting so my workflow would run whenever a document was uploaded into a document library.

The caveat is SharePoint runs the workflow immediately upon upload and doesn’t wait for an initial check-in to occur (which is a separate step if your document library has required metadata fields that must be filled out).

I needed a way to make the workflow wait for the initial check-in to occur so all the data would be present that was needed by the workflow.

Since the “Current Item” variable in my workflow included a “Level” field (indicates the check-in status of an item), I initially thought I could use the Wait for Field Change in Current Item action and wait for that field to change to “1.”

However, that didn’t work. The workflow would get stuck at the wait action every single time and never come out of it (even when the level changed to 1). I don’t know why, but for some reason that action doesn’t work as expected with the “Level” field.

The good news is I finally found a solution that worked: using a loop.

As shown in the following screenshot, I added a “Wait for Check-In” loop that checks the value of Current Item:Level once per minute and exits the loop when the value is no longer 255 (checked out).

So far that’s worked consistently.

Workflow loop to wait for check-in

SSRS Error – “Element <Query> of parameter query is missing or invalid”

As I told someone earlier this morning, I have mixed feelings about SSRS for SharePoint reporting. SSRS is a great tool, but it’s very obvious at times that it wasn’t originally designed for reporting against SharePoint data. Even in the 2012 version, the UI and behavior of SSRS with SharePoint can be a bit quirky.

Today’s strange issue was the following error: “Element <Query> of parameter query is missing or invalid”

I got this error when I tried to run a very basic report in Report Builder 3.0. I was pulling data from a list in SharePoint 2013 and using the XML (Lists.asmx) connection type.

At first, I thought I had the problem described in this StackOverflow post:
http://stackoverflow.com/questions/1074529/soap-call-with-query-on-result-ssrs-sharepoint/1210625#1210625

The post describes how SSRS fails to send your query properly if you directly embed CAML markup in your query XML. Instead, you must create a parameter called “query” (all lowercase) in your dataset and put your CAML markup in there. I won’t reproduce all of that here because the SO post does a great job illustrating it.

But…

Even after I did that, I was still getting the error. The reason turned out to be a case-sensitivity problem. I’d copied my original web service query XML from another blog post, and the author of the original post had a syntax error in his XML that I missed.

Here’s how his query should have looked:

<Query>
  <SoapAction>http://schemas.microsoft.com/sharepoint/soap/GetListItems</SoapAction>
  <Method Namespace="http://schemas.microsoft.com/sharepoint/soap/" Name="GetListItems">
    <Parameters>
      <Parameter Name="listName">
        <DefaultValue>My List</DefaultValue>
      </Parameter>
      <Parameter Name="query" Type="xml"></Parameter>
      <Parameter Name="viewFields" Type="xml"></Parameter>
    </Parameters>
  </Method>
  <ElementPath IgnoreNamespaces="True">*</ElementPath>
</Query>

In the code I originally copied from his blog, the “Type” attribute for the query parameter was spelled as “type” (all lowercase). Because XML processing in SSRS is case-sensitive, the lowercased “type” attribute caused the error.

Solution for missing SharePoint 2013 search display templates

I was doing some client work today and came across a need to configure a Content Search web part on a page.

I added the web part to the page and immediately got an error about the “Control_List.js” template. The error said the template was missing or had a syntax error.

The first thing I did was navigate to the display template folder at Master Page Gallery > Display Templates > Content Web Parts.

To my surprise, the folder was empty. However, the other display template folder (Display Templates > Search) had all the normal templates in it, so I wasn’t sure why only the web part templates were missing. I did a Google search and found absolutely nothing. The client’s environment had been upgraded from SharePoint 2010 to SharePoint 2013 earlier this year, so it’s certainly possible the display templates weren’t provisioned properly during the upgrade.

In the end, I discovered the fix was to deactivate and then re-activate the SearchTemplatesAndResources feature (with id “8b2c6bcb-c47f-4f17-8127-f8eae47a44dd”) on the site collection. This feature isn’t visible in the UI, so I did with PowerShell using the Disable-SPFeature and Enable-SPFeature cmdlets.