Fix the duplicate checking logic:
Your duplicate checking logic is wrong. You needed to keep the terms in an array and then check if the term already exist in the array to determine if it’s a duplicate.
So instead of if ( $dupe == 0 ) :
condition and wrong loop nesting, it’ll be like:
if ( have_posts() ) :
echo '<ul class="filter">';
echo '<li class="current-menu-item"><a href="#" data-filter="*">' . __( 'All' ) . '</a></li>';
$unique_terms = array(); // instead of $dupe = 0;
while ( have_posts() ) : the_post();
$term_list = wp_get_post_terms( $post->ID, 'media_blog_category', array( 'fields' => 'all' ) );
foreach( $term_list as $term ) :
if( ! in_array( $term->term_id, $unique_terms ) ):
array_push( $unique_terms, $term->term_id );
echo '<li><a href="#" data-filter=".media_blog_category-' . $term->slug . '">' . $term->name . '</a></li>';
endif;
endforeach; //term_list
endwhile;
echo '</ul>';
endif; //WP_Query
This should work as you’ve wanted.
A better solution:
Your CODE will work after fixing with the above logic. However, you can make it more efficient with the following CODE:
if ( is_post_type_archive( 'media_blog' ) ) :
$args = array(
'post_type' => 'media_blog',
'posts_per_page' => 16, // same as the pre_get_posts
'post_status' => 'publish',
'paged' => get_query_var( 'paged' ),
'fields' => 'ids' // for this specific case, all you need are the IDs
);
$wp_query = new WP_Query( $args );
if ( have_posts() ) :
echo '<ul class="filter">';
echo '<li class="current-menu-item"><a href="#" data-filter="*">' . __( 'All' ) . '</a></li>';
$term_list = wp_get_object_terms( $wp_query->get_posts(), 'media_blog_category' );
foreach( $term_list as $term ) :
echo '<li><a href="#" data-filter=".media_blog_category-' . $term->slug . '">' . $term->name . '</a></li>';
endforeach; //term_list
echo '</ul>';
endif; //WP_Query
wp_reset_query();
endif; //media_blog