Disclaimer: I am trying to help someone with adding another section to their WordPress site. I did not write most of this code.
I am using a different custom post type for each WP_Query loop. Both loops work fine on their own, but when I try to run them on the same page, the second one doesn’t show any posts.
Things I have tried:
- wp_reset_query();
 - wp_reset_postdata();
 - changing the names of $query and $args so each is unique
 - moving the reset function to inside if() (but still outside the while loop)
 
I have looked at every post I can find on the subject and tried all the suggestions, but nothing is working. Surely I am missing something.. Maybe another set of eyes can help me find the problem. I have posted the relevant code below.
/* ---- First Loop ---- */
<?php
    $args = array(
        'post_type'      => 'casestudies',
        'post_status'    => 'publish',
        'order'          => 'ASC',
        'posts_per_page' => -1
    );
                        
    $query = new WP_Query( $args );
    if ( $query->have_posts() ) :
        while ( $query->have_posts() ) : 
            $query->the_post();
            /* ---- Do Stuff ---- */
        endwhile;               
    endif;
    wp_reset_query();
?>
/* ---- Second Loop ---- */
<?php
    $args = array(
        'post_type'      => 'whitepages',
        'post_status'    => 'publish',
        'order'          => 'ASC',
        'posts_per_page' => -1
    );
                        
    $query = new WP_Query( $args );
    if ( $query->have_posts() ) :
        while ( $query->have_posts() ) : 
            $query->the_post();
            /* ---- Do Stuff ---- */    
                                
        endwhile;
    endif;
    wp_reset_query();
?>
Edit:
I found the solution with help from the accepted answer. I posted what I did to fix everything in another answer below.
Advertisement
Answer
Having just tried this code in my local environment, with the only change being the post_type values in you $args arrays, it seems to be working fine.
What I would recommend doing, as it is as follows:
- Double checking the value for 
post_typematches the post type’s slug. This could just be a case of misspelling, and it’s something that tripped me up more times than I’d like to admit over the years.
You can find this by going tofunctions.phpand looking forregister_post_typefunction calls. - Checking whether there are in fact published posts under that post type. Again, this is something I’ve been caught out by a few times too.
 
Additionally, you might want to think about perhaps neatening up the code a little, just to prevent potentially missing something and also to make it more manageable in the future.
Looping over an available post types array where you then construct a WP_Query for each of the available post types is my preference of going about a task like what you described, it looks like this:
<?php
    $post_types       = array( 'yourposttype', 'yourotherposttype' );
    $common_arguments = array(
        'post_status'    => 'publish',
        'order'          => 'ASC',
        'posts_per_page' => -1,
    );
?>
<?php foreach ( $post_types as $post_type ): ?>
    <?php
        $post_type_argument = array( 'post_type' => $post_type );
        $arguments          = array_merge( $common_arguments, $post_type_argument );
        $query              = new WP_Query( $arguments );
    ?>
    <?php if ( $query->have_posts() ): ?>
        <?php while ( $query->have_posts() ) : $query->the_post(); ?>
            <?php // Example output ?>
            <?php the_title(); ?>
        <?php endwhile; ?>
        <?php wp_reset_postdata(); ?>
    <?php endif; ?>
    
<?php endforeach; ?>
This way if you ever need to show another post type, you can add it to the $post_types array without having to duplicate blocks of code.
And finally, you were correct when you used wp_reset_postdata(), it’s the recommended function to run after looping over a custom WP_Query, wp_reset_query() is a little superfluous in this case.
You can read this answer by Stephen Harris for a bit more depth.